{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "FinRL_StockTrading_Fundamental.ipynb",
      "provenance": [],
      "collapsed_sections": [
        "uijiWgkuh1jB",
        "MRiOtrywfAo1",
        "_gDkU-j-fCmZ",
        "3Zpv4S0-fDBv"
      ],
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.6.12"
    },
    "pycharm": {
      "stem_cell": {
        "cell_type": "raw",
        "metadata": {
          "collapsed": false
        },
        "source": []
      }
    },
    "accelerator": "GPU"
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "view-in-github",
        "colab_type": "text"
      },
      "source": [
        "<a href=\"https://colab.research.google.com/github/AI4Finance-Foundation/FinRL/blob/master/FinRL_StockTrading_Fundamental.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gXaoZs2lh1hi"
      },
      "source": [
        "# Automated stock trading using FinRL with financial data\n",
        "\n",
        "Trained a Deep Reinforcement Learning model using FinRL and companies' financial ratio, and then backtested the model to examine how well-trained the model is\n",
        "\n",
        "* This Google Colabolatory notebook is based on the tutorial of FinRL: https://towardsdatascience.com/finrl-for-quantitative-finance-tutorial-for-multiple-stock-trading-7b00763b7530\n",
        "\n",
        "* This project is a final project of the almuni-mentored research project at Columbia University, Application of Reinforcement Learning to Finance, mentored by Bruce Yang from AI4Finance.\n",
        "* For more detailed explanation, please check out my Medium post: https://medium.com/@mariko.sawada1/automated-stock-trading-with-deep-reinforcement-learning-and-financial-data-a63286ccbe2b\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lGunVt8oLCVS"
      },
      "source": [
        "# Content"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HOzAKQ-SLGX6"
      },
      "source": [
        "* [1. Problem Definition](#0)\n",
        "* [2. Getting Started - Load Python packages](#1)\n",
        "    * [2.1. Install Packages](#1.1)    \n",
        "    * [2.2. Check Additional Packages](#1.2)\n",
        "    * [2.3. Import Packages](#1.3)\n",
        "    * [2.4. Create Folders](#1.4)\n",
        "* [3. Download Data](#2)\n",
        "* [4. Preprocess fundamental Data](#3)        \n",
        "    * [4-1 Import financial data](#3.1)\n",
        "    * [4-2 Specify items needed to calculate financial ratios](#3.2)\n",
        "    * [4-3 Calculate financial ratios](#3.3)\n",
        "    * [4-4 Deal with NAs and infinite values](#3.4)\n",
        "    * [4-5 Merge stock price data and ratios into one dataframe](#3.5)\n",
        "    * [4-6 Calculate market valuation ratios using daily stock price data](#3.6)\n",
        "* [5.Build Environment](#4)  \n",
        "    * [5.1. Training & Trade Data Split](#4.1)\n",
        "    * [5.2. User-defined Environment](#4.2)   \n",
        "    * [5.3. Initialize Environment](#4.3)    \n",
        "* [6.Implement DRL Algorithms](#5)  \n",
        "* [7.Backtesting Performance](#6)  \n",
        "    * [7.1. BackTestStats](#6.1)\n",
        "    * [7.2. BackTestPlot](#6.2)   \n",
        "    * [7.3. Baseline Stats](#6.3)   \n",
        "    * [7.3. Compare to Stock Market Index](#6.4)             "
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "sApkDlD9LIZv"
      },
      "source": [
        "<a id='0'></a>\n",
        "# Part 1. Problem Definition"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HjLD2TZSLKZ-"
      },
      "source": [
        "This problem is to design an automated trading solution for single stock trading. We model the stock trading process as a Markov Decision Process (MDP). We then formulate our trading goal as a maximization problem.\n",
        "\n",
        "The algorithm is trained using Deep Reinforcement Learning (DRL) algorithms and the components of the reinforcement learning environment are:\n",
        "\n",
        "\n",
        "* Action: The action space describes the allowed actions that the agent interacts with the\n",
        "environment. Normally, a ∈ A includes three actions: a ∈ {−1, 0, 1}, where −1, 0, 1 represent\n",
        "selling, holding, and buying one stock. Also, an action can be carried upon multiple shares. We use\n",
        "an action space {−k, ..., −1, 0, 1, ..., k}, where k denotes the number of shares. For example, \"Buy\n",
        "10 shares of AAPL\" or \"Sell 10 shares of AAPL\" are 10 or −10, respectively\n",
        "\n",
        "* Reward function: r(s, a, s′) is the incentive mechanism for an agent to learn a better action. The change of the portfolio value when action a is taken at state s and arriving at new state s',  i.e., r(s, a, s′) = v′ − v, where v′ and v represent the portfolio\n",
        "values at state s′ and s, respectively\n",
        "\n",
        "* State: The state space describes the observations that the agent receives from the environment. Just as a human trader needs to analyze various information before executing a trade, so\n",
        "our trading agent observes many different features to better learn in an interactive environment.\n",
        "\n",
        "* Environment: Dow 30 consituents\n",
        "\n",
        "\n",
        "The data of the single stock that we will be using for this case study is obtained from Yahoo Finance API. The data contains Open-High-Low-Close price and volume.\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Ffsre789LY08"
      },
      "source": [
        "<a id='1'></a>\n",
        "# Part 2. Load Python Packages"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Uy5_PTmOh1hj"
      },
      "source": [
        "<a id='1.1'></a>\n",
        "## 2.1. Install all the packages through FinRL library\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "mPT0ipYE28wL",
        "outputId": "34ca00d4-0612-4845-c0b4-81a84e9f6d32"
      },
      "source": [
        "## install finrl library\n",
        "!pip install git+https://github.com/AI4Finance-LLC/FinRL-Library.git"
      ],
      "execution_count": 1,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Collecting git+https://github.com/AI4Finance-LLC/FinRL-Library.git\n",
            "  Cloning https://github.com/AI4Finance-LLC/FinRL-Library.git to /tmp/pip-req-build-avwct7pb\n",
            "  Running command git clone -q https://github.com/AI4Finance-LLC/FinRL-Library.git /tmp/pip-req-build-avwct7pb\n",
            "Collecting pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2\n",
            "  Cloning https://github.com/quantopian/pyfolio.git to /tmp/pip-install-sps4f25k/pyfolio_2efe9a99238a42588250d6733a01d260\n",
            "  Running command git clone -q https://github.com/quantopian/pyfolio.git /tmp/pip-install-sps4f25k/pyfolio_2efe9a99238a42588250d6733a01d260\n",
            "Collecting elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl\n",
            "  Cloning https://github.com/AI4Finance-Foundation/ElegantRL.git to /tmp/pip-install-sps4f25k/elegantrl_28233bba5b454d3399006626d813b65b\n",
            "  Running command git clone -q https://github.com/AI4Finance-Foundation/ElegantRL.git /tmp/pip-install-sps4f25k/elegantrl_28233bba5b454d3399006626d813b65b\n",
            "Requirement already satisfied: numpy>=1.17.3 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (1.19.5)\n",
            "Requirement already satisfied: pandas>=1.1.5 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (1.1.5)\n",
            "Collecting stockstats>=0.4.0\n",
            "  Downloading stockstats-0.4.1-py2.py3-none-any.whl (19 kB)\n",
            "Collecting yfinance\n",
            "  Downloading yfinance-0.1.69-py2.py3-none-any.whl (26 kB)\n",
            "Collecting elegantrl\n",
            "  Downloading elegantrl-0.3.3-py3-none-any.whl (234 kB)\n",
            "\u001b[K     |████████████████████████████████| 234 kB 26.4 MB/s \n",
            "\u001b[?25hRequirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (3.2.2)\n",
            "Requirement already satisfied: scikit-learn>=0.21.0 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (1.0.2)\n",
            "Requirement already satisfied: gym>=0.17 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (0.17.3)\n",
            "Collecting stable-baselines3[extra]\n",
            "  Downloading stable_baselines3-1.3.0-py3-none-any.whl (174 kB)\n",
            "\u001b[K     |████████████████████████████████| 174 kB 73.9 MB/s \n",
            "\u001b[?25hCollecting ray[default]\n",
            "  Downloading ray-1.9.2-cp37-cp37m-manylinux2014_x86_64.whl (57.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 57.6 MB 1.2 MB/s \n",
            "\u001b[?25hCollecting lz4\n",
            "  Downloading lz4-3.1.10-cp37-cp37m-manylinux2010_x86_64.whl (1.8 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.8 MB 63.9 MB/s \n",
            "\u001b[?25hCollecting tensorboardX\n",
            "  Downloading tensorboardX-2.4.1-py2.py3-none-any.whl (124 kB)\n",
            "\u001b[K     |████████████████████████████████| 124 kB 83.4 MB/s \n",
            "\u001b[?25hCollecting gputil\n",
            "  Downloading GPUtil-1.4.0.tar.gz (5.5 kB)\n",
            "Collecting exchange_calendars\n",
            "  Downloading exchange_calendars-3.5.tar.gz (147 kB)\n",
            "\u001b[K     |████████████████████████████████| 147 kB 68.3 MB/s \n",
            "\u001b[?25hCollecting alpaca_trade_api\n",
            "  Downloading alpaca_trade_api-1.4.3-py3-none-any.whl (36 kB)\n",
            "Collecting ccxt>=1.66.32\n",
            "  Downloading ccxt-1.67.31-py2.py3-none-any.whl (2.3 MB)\n",
            "\u001b[K     |████████████████████████████████| 2.3 MB 61.2 MB/s \n",
            "\u001b[?25hCollecting jqdatasdk\n",
            "  Downloading jqdatasdk-1.8.10-py3-none-any.whl (153 kB)\n",
            "\u001b[K     |████████████████████████████████| 153 kB 76.3 MB/s \n",
            "\u001b[?25hCollecting wrds\n",
            "  Downloading wrds-3.1.1-py3-none-any.whl (12 kB)\n",
            "Requirement already satisfied: pytest in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (3.6.4)\n",
            "Requirement already satisfied: setuptools>=41.4.0 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (57.4.0)\n",
            "Requirement already satisfied: wheel>=0.33.6 in /usr/local/lib/python3.7/dist-packages (from finrl==0.3.4) (0.37.1)\n",
            "Collecting pre-commit\n",
            "  Downloading pre_commit-2.16.0-py2.py3-none-any.whl (191 kB)\n",
            "\u001b[K     |████████████████████████████████| 191 kB 75.1 MB/s \n",
            "\u001b[?25hCollecting pybullet\n",
            "  Downloading pybullet-3.2.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (90.8 MB)\n",
            "\u001b[K     |████████████████████████████████| 90.8 MB 298 bytes/s \n",
            "\u001b[?25hRequirement already satisfied: torch in /usr/local/lib/python3.7/dist-packages (from elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl->finrl==0.3.4) (1.10.0+cu111)\n",
            "Requirement already satisfied: opencv-python in /usr/local/lib/python3.7/dist-packages (from elegantrl@ git+https://github.com/AI4Finance-Foundation/ElegantRL.git#egg=elegantrl->finrl==0.3.4) (4.1.2.30)\n",
            "Collecting box2d-py\n",
            "  Downloading box2d_py-2.3.8-cp37-cp37m-manylinux1_x86_64.whl (448 kB)\n",
            "\u001b[K     |████████████████████████████████| 448 kB 60.4 MB/s \n",
            "\u001b[?25hRequirement already satisfied: ipython>=3.2.3 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (5.5.0)\n",
            "Requirement already satisfied: pytz>=2014.10 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (2018.9)\n",
            "Requirement already satisfied: scipy>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (1.4.1)\n",
            "Requirement already satisfied: seaborn>=0.7.1 in /usr/local/lib/python3.7/dist-packages (from pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.11.2)\n",
            "Collecting empyrical>=0.5.0\n",
            "  Downloading empyrical-0.5.5.tar.gz (52 kB)\n",
            "\u001b[K     |████████████████████████████████| 52 kB 2.1 MB/s \n",
            "\u001b[?25hRequirement already satisfied: requests>=2.18.4 in /usr/local/lib/python3.7/dist-packages (from ccxt>=1.66.32->finrl==0.3.4) (2.23.0)\n",
            "Collecting yarl==1.7.2\n",
            "  Downloading yarl-1.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (271 kB)\n",
            "\u001b[K     |████████████████████████████████| 271 kB 75.7 MB/s \n",
            "\u001b[?25hCollecting aiohttp>=3.8\n",
            "  Downloading aiohttp-3.8.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (1.1 MB)\n",
            "\u001b[K     |████████████████████████████████| 1.1 MB 58.7 MB/s \n",
            "\u001b[?25hCollecting cryptography>=2.6.1\n",
            "  Downloading cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl (3.6 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.6 MB 58.9 MB/s \n",
            "\u001b[?25hRequirement already satisfied: certifi>=2018.1.18 in /usr/local/lib/python3.7/dist-packages (from ccxt>=1.66.32->finrl==0.3.4) (2021.10.8)\n",
            "Collecting aiodns>=1.1.1\n",
            "  Downloading aiodns-3.0.0-py3-none-any.whl (5.0 kB)\n",
            "Collecting multidict>=4.0\n",
            "  Downloading multidict-5.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (160 kB)\n",
            "\u001b[K     |████████████████████████████████| 160 kB 67.6 MB/s \n",
            "\u001b[?25hRequirement already satisfied: idna>=2.0 in /usr/local/lib/python3.7/dist-packages (from yarl==1.7.2->ccxt>=1.66.32->finrl==0.3.4) (2.10)\n",
            "Requirement already satisfied: typing-extensions>=3.7.4 in /usr/local/lib/python3.7/dist-packages (from yarl==1.7.2->ccxt>=1.66.32->finrl==0.3.4) (3.10.0.2)\n",
            "Collecting pycares>=4.0.0\n",
            "  Downloading pycares-4.1.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (291 kB)\n",
            "\u001b[K     |████████████████████████████████| 291 kB 70.8 MB/s \n",
            "\u001b[?25hRequirement already satisfied: charset-normalizer<3.0,>=2.0 in /usr/local/lib/python3.7/dist-packages (from aiohttp>=3.8->ccxt>=1.66.32->finrl==0.3.4) (2.0.10)\n",
            "Collecting aiosignal>=1.1.2\n",
            "  Downloading aiosignal-1.2.0-py3-none-any.whl (8.2 kB)\n",
            "Requirement already satisfied: attrs>=17.3.0 in /usr/local/lib/python3.7/dist-packages (from aiohttp>=3.8->ccxt>=1.66.32->finrl==0.3.4) (21.4.0)\n",
            "Collecting asynctest==0.13.0\n",
            "  Downloading asynctest-0.13.0-py3-none-any.whl (26 kB)\n",
            "Collecting async-timeout<5.0,>=4.0.0a3\n",
            "  Downloading async_timeout-4.0.2-py3-none-any.whl (5.8 kB)\n",
            "Collecting frozenlist>=1.1.1\n",
            "  Downloading frozenlist-1.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (192 kB)\n",
            "\u001b[K     |████████████████████████████████| 192 kB 73.4 MB/s \n",
            "\u001b[?25hRequirement already satisfied: cffi>=1.12 in /usr/local/lib/python3.7/dist-packages (from cryptography>=2.6.1->ccxt>=1.66.32->finrl==0.3.4) (1.15.0)\n",
            "Requirement already satisfied: pycparser in /usr/local/lib/python3.7/dist-packages (from cffi>=1.12->cryptography>=2.6.1->ccxt>=1.66.32->finrl==0.3.4) (2.21)\n",
            "Requirement already satisfied: pandas-datareader>=0.2 in /usr/local/lib/python3.7/dist-packages (from empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.9.0)\n",
            "Requirement already satisfied: pyglet<=1.5.0,>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from gym>=0.17->finrl==0.3.4) (1.5.0)\n",
            "Requirement already satisfied: cloudpickle<1.7.0,>=1.2.0 in /usr/local/lib/python3.7/dist-packages (from gym>=0.17->finrl==0.3.4) (1.3.0)\n",
            "Requirement already satisfied: pygments in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (2.6.1)\n",
            "Requirement already satisfied: traitlets>=4.2 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (5.1.1)\n",
            "Requirement already satisfied: pexpect in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (4.8.0)\n",
            "Requirement already satisfied: decorator in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (4.4.2)\n",
            "Requirement already satisfied: pickleshare in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.7.5)\n",
            "Requirement already satisfied: simplegeneric>0.8 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.8.1)\n",
            "Requirement already satisfied: prompt-toolkit<2.0.0,>=1.0.4 in /usr/local/lib/python3.7/dist-packages (from ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (1.0.18)\n",
            "Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.4) (0.11.0)\n",
            "Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.4) (3.0.6)\n",
            "Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.4) (2.8.2)\n",
            "Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->finrl==0.3.4) (1.3.2)\n",
            "Requirement already satisfied: lxml in /usr/local/lib/python3.7/dist-packages (from pandas-datareader>=0.2->empyrical>=0.5.0->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (4.2.6)\n",
            "Requirement already satisfied: six>=1.9.0 in /usr/local/lib/python3.7/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (1.15.0)\n",
            "Requirement already satisfied: wcwidth in /usr/local/lib/python3.7/dist-packages (from prompt-toolkit<2.0.0,>=1.0.4->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.2.5)\n",
            "Requirement already satisfied: future in /usr/local/lib/python3.7/dist-packages (from pyglet<=1.5.0,>=1.4.0->gym>=0.17->finrl==0.3.4) (0.16.0)\n",
            "Requirement already satisfied: chardet<4,>=3.0.2 in /usr/local/lib/python3.7/dist-packages (from requests>=2.18.4->ccxt>=1.66.32->finrl==0.3.4) (3.0.4)\n",
            "Requirement already satisfied: urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from requests>=2.18.4->ccxt>=1.66.32->finrl==0.3.4) (1.24.3)\n",
            "Requirement already satisfied: joblib>=0.11 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.21.0->finrl==0.3.4) (1.1.0)\n",
            "Requirement already satisfied: threadpoolctl>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from scikit-learn>=0.21.0->finrl==0.3.4) (3.0.0)\n",
            "Collecting msgpack==1.0.2\n",
            "  Downloading msgpack-1.0.2-cp37-cp37m-manylinux1_x86_64.whl (273 kB)\n",
            "\u001b[K     |████████████████████████████████| 273 kB 73.9 MB/s \n",
            "\u001b[?25hCollecting websocket-client<2,>=0.56.0\n",
            "  Downloading websocket_client-1.2.3-py3-none-any.whl (53 kB)\n",
            "\u001b[K     |████████████████████████████████| 53 kB 2.8 MB/s \n",
            "\u001b[?25hCollecting alpaca_trade_api\n",
            "  Downloading alpaca_trade_api-1.4.2-py3-none-any.whl (36 kB)\n",
            "  Downloading alpaca_trade_api-1.4.1-py3-none-any.whl (36 kB)\n",
            "  Downloading alpaca_trade_api-1.4.0-py3-none-any.whl (34 kB)\n",
            "  Downloading alpaca_trade_api-1.3.0-py3-none-any.whl (43 kB)\n",
            "\u001b[K     |████████████████████████████████| 43 kB 2.3 MB/s \n",
            "\u001b[?25h  Downloading alpaca_trade_api-1.2.3-py3-none-any.whl (40 kB)\n",
            "\u001b[K     |████████████████████████████████| 40 kB 7.3 MB/s \n",
            "\u001b[?25hCollecting websockets<10,>=8.0\n",
            "  Downloading websockets-9.1-cp37-cp37m-manylinux2010_x86_64.whl (103 kB)\n",
            "\u001b[K     |████████████████████████████████| 103 kB 77.3 MB/s \n",
            "\u001b[?25hCollecting pyluach\n",
            "  Downloading pyluach-1.3.0-py3-none-any.whl (17 kB)\n",
            "Requirement already satisfied: toolz in /usr/local/lib/python3.7/dist-packages (from exchange_calendars->finrl==0.3.4) (0.11.2)\n",
            "Requirement already satisfied: korean_lunar_calendar in /usr/local/lib/python3.7/dist-packages (from exchange_calendars->finrl==0.3.4) (0.2.1)\n",
            "Collecting thriftpy2>=0.3.9\n",
            "  Downloading thriftpy2-0.4.14.tar.gz (361 kB)\n",
            "\u001b[K     |████████████████████████████████| 361 kB 78.3 MB/s \n",
            "\u001b[?25hCollecting pymysql>=0.7.6\n",
            "  Downloading PyMySQL-1.0.2-py3-none-any.whl (43 kB)\n",
            "\u001b[K     |████████████████████████████████| 43 kB 2.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: SQLAlchemy>=1.2.8 in /usr/local/lib/python3.7/dist-packages (from jqdatasdk->finrl==0.3.4) (1.4.29)\n",
            "Requirement already satisfied: importlib-metadata in /usr/local/lib/python3.7/dist-packages (from SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.4) (4.10.0)\n",
            "Requirement already satisfied: greenlet!=0.4.17 in /usr/local/lib/python3.7/dist-packages (from SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.4) (1.1.2)\n",
            "Collecting ply<4.0,>=3.4\n",
            "  Downloading ply-3.11-py2.py3-none-any.whl (49 kB)\n",
            "\u001b[K     |████████████████████████████████| 49 kB 7.6 MB/s \n",
            "\u001b[?25hRequirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/dist-packages (from importlib-metadata->SQLAlchemy>=1.2.8->jqdatasdk->finrl==0.3.4) (3.7.0)\n",
            "Requirement already satisfied: ptyprocess>=0.5 in /usr/local/lib/python3.7/dist-packages (from pexpect->ipython>=3.2.3->pyfolio@ git+https://github.com/quantopian/pyfolio.git#egg=pyfolio-0.9.2->finrl==0.3.4) (0.7.0)\n",
            "Collecting pyyaml>=5.1\n",
            "  Downloading PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl (596 kB)\n",
            "\u001b[K     |████████████████████████████████| 596 kB 66.2 MB/s \n",
            "\u001b[?25hCollecting identify>=1.0.0\n",
            "  Downloading identify-2.4.3-py2.py3-none-any.whl (98 kB)\n",
            "\u001b[K     |████████████████████████████████| 98 kB 9.6 MB/s \n",
            "\u001b[?25hCollecting nodeenv>=0.11.1\n",
            "  Downloading nodeenv-1.6.0-py2.py3-none-any.whl (21 kB)\n",
            "Collecting virtualenv>=20.0.8\n",
            "  Downloading virtualenv-20.13.0-py2.py3-none-any.whl (6.5 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.5 MB 50.1 MB/s \n",
            "\u001b[?25hRequirement already satisfied: toml in /usr/local/lib/python3.7/dist-packages (from pre-commit->finrl==0.3.4) (0.10.2)\n",
            "Collecting cfgv>=2.0.0\n",
            "  Downloading cfgv-3.3.1-py2.py3-none-any.whl (7.3 kB)\n",
            "Collecting platformdirs<3,>=2\n",
            "  Downloading platformdirs-2.4.1-py3-none-any.whl (14 kB)\n",
            "Collecting distlib<1,>=0.3.1\n",
            "  Downloading distlib-0.3.4-py2.py3-none-any.whl (461 kB)\n",
            "\u001b[K     |████████████████████████████████| 461 kB 65.2 MB/s \n",
            "\u001b[?25hRequirement already satisfied: filelock<4,>=3.2 in /usr/local/lib/python3.7/dist-packages (from virtualenv>=20.0.8->pre-commit->finrl==0.3.4) (3.4.2)\n",
            "Requirement already satisfied: pluggy<0.8,>=0.5 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.4) (0.7.1)\n",
            "Requirement already satisfied: more-itertools>=4.0.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.4) (8.12.0)\n",
            "Requirement already satisfied: atomicwrites>=1.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.4) (1.4.0)\n",
            "Requirement already satisfied: py>=1.5.0 in /usr/local/lib/python3.7/dist-packages (from pytest->finrl==0.3.4) (1.11.0)\n",
            "Collecting redis>=3.5.0\n",
            "  Downloading redis-4.1.0-py3-none-any.whl (171 kB)\n",
            "\u001b[K     |████████████████████████████████| 171 kB 77.2 MB/s \n",
            "\u001b[?25hRequirement already satisfied: protobuf>=3.15.3 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (3.17.3)\n",
            "Requirement already satisfied: grpcio>=1.28.1 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (1.43.0)\n",
            "Requirement already satisfied: click>=7.0 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (7.1.2)\n",
            "Requirement already satisfied: jsonschema in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (4.3.3)\n",
            "Requirement already satisfied: smart-open in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (5.2.1)\n",
            "Collecting opencensus\n",
            "  Downloading opencensus-0.8.0-py2.py3-none-any.whl (128 kB)\n",
            "\u001b[K     |████████████████████████████████| 128 kB 80.3 MB/s \n",
            "\u001b[?25hCollecting aiohttp-cors\n",
            "  Downloading aiohttp_cors-0.7.0-py3-none-any.whl (27 kB)\n",
            "Collecting colorful\n",
            "  Downloading colorful-0.5.4-py2.py3-none-any.whl (201 kB)\n",
            "\u001b[K     |████████████████████████████████| 201 kB 79.8 MB/s \n",
            "\u001b[?25hCollecting py-spy>=0.2.0\n",
            "  Downloading py_spy-0.3.11-py2.py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl (3.0 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.0 MB 61.5 MB/s \n",
            "\u001b[?25hRequirement already satisfied: prometheus-client>=0.7.1 in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (0.12.0)\n",
            "Collecting gpustat>=1.0.0b1\n",
            "  Downloading gpustat-1.0.0b1.tar.gz (82 kB)\n",
            "\u001b[K     |████████████████████████████████| 82 kB 313 kB/s \n",
            "\u001b[?25hCollecting aioredis<2\n",
            "  Downloading aioredis-1.3.1-py3-none-any.whl (65 kB)\n",
            "\u001b[K     |████████████████████████████████| 65 kB 4.5 MB/s \n",
            "\u001b[?25hCollecting hiredis\n",
            "  Downloading hiredis-2.0.0-cp37-cp37m-manylinux2010_x86_64.whl (85 kB)\n",
            "\u001b[K     |████████████████████████████████| 85 kB 4.7 MB/s \n",
            "\u001b[?25hRequirement already satisfied: nvidia-ml-py3>=7.352.0 in /usr/local/lib/python3.7/dist-packages (from gpustat>=1.0.0b1->ray[default]->finrl==0.3.4) (7.352.0)\n",
            "Requirement already satisfied: psutil in /usr/local/lib/python3.7/dist-packages (from gpustat>=1.0.0b1->ray[default]->finrl==0.3.4) (5.4.8)\n",
            "Collecting blessed>=1.17.1\n",
            "  Downloading blessed-1.19.0-py2.py3-none-any.whl (57 kB)\n",
            "\u001b[K     |████████████████████████████████| 57 kB 7.1 MB/s \n",
            "\u001b[?25hCollecting deprecated>=1.2.3\n",
            "  Downloading Deprecated-1.2.13-py2.py3-none-any.whl (9.6 kB)\n",
            "Requirement already satisfied: packaging>=21.3 in /usr/local/lib/python3.7/dist-packages (from redis>=3.5.0->ray[default]->finrl==0.3.4) (21.3)\n",
            "Requirement already satisfied: wrapt<2,>=1.10 in /usr/local/lib/python3.7/dist-packages (from deprecated>=1.2.3->redis>=3.5.0->ray[default]->finrl==0.3.4) (1.13.3)\n",
            "Requirement already satisfied: pyrsistent!=0.17.0,!=0.17.1,!=0.17.2,>=0.14.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema->ray[default]->finrl==0.3.4) (0.18.0)\n",
            "Requirement already satisfied: importlib-resources>=1.4.0 in /usr/local/lib/python3.7/dist-packages (from jsonschema->ray[default]->finrl==0.3.4) (5.4.0)\n",
            "Requirement already satisfied: google-api-core<3.0.0,>=1.0.0 in /usr/local/lib/python3.7/dist-packages (from opencensus->ray[default]->finrl==0.3.4) (1.26.3)\n",
            "Collecting opencensus-context==0.1.2\n",
            "  Downloading opencensus_context-0.1.2-py2.py3-none-any.whl (4.4 kB)\n",
            "Requirement already satisfied: google-auth<2.0dev,>=1.21.1 in /usr/local/lib/python3.7/dist-packages (from google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (1.35.0)\n",
            "Requirement already satisfied: googleapis-common-protos<2.0dev,>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (1.54.0)\n",
            "Requirement already satisfied: cachetools<5.0,>=2.0.0 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (4.2.4)\n",
            "Requirement already satisfied: rsa<5,>=3.1.4 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (4.8)\n",
            "Requirement already satisfied: pyasn1-modules>=0.2.1 in /usr/local/lib/python3.7/dist-packages (from google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (0.2.8)\n",
            "Requirement already satisfied: pyasn1<0.5.0,>=0.4.6 in /usr/local/lib/python3.7/dist-packages (from pyasn1-modules>=0.2.1->google-auth<2.0dev,>=1.21.1->google-api-core<3.0.0,>=1.0.0->opencensus->ray[default]->finrl==0.3.4) (0.4.8)\n",
            "Requirement already satisfied: tabulate in /usr/local/lib/python3.7/dist-packages (from ray[default]->finrl==0.3.4) (0.8.9)\n",
            "Requirement already satisfied: pillow in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.4) (7.1.2)\n",
            "Requirement already satisfied: tensorboard>=2.2.0 in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.4) (2.7.0)\n",
            "Requirement already satisfied: atari-py~=0.2.0 in /usr/local/lib/python3.7/dist-packages (from stable-baselines3[extra]->finrl==0.3.4) (0.2.9)\n",
            "Requirement already satisfied: werkzeug>=0.11.15 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (1.0.1)\n",
            "Requirement already satisfied: tensorboard-plugin-wit>=1.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (1.8.1)\n",
            "Requirement already satisfied: tensorboard-data-server<0.7.0,>=0.6.0 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (0.6.1)\n",
            "Requirement already satisfied: google-auth-oauthlib<0.5,>=0.4.1 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (0.4.6)\n",
            "Requirement already satisfied: markdown>=2.6.8 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (3.3.6)\n",
            "Requirement already satisfied: absl-py>=0.4 in /usr/local/lib/python3.7/dist-packages (from tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (0.12.0)\n",
            "Requirement already satisfied: requests-oauthlib>=0.7.0 in /usr/local/lib/python3.7/dist-packages (from google-auth-oauthlib<0.5,>=0.4.1->tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (1.3.0)\n",
            "Requirement already satisfied: oauthlib>=3.0.0 in /usr/local/lib/python3.7/dist-packages (from requests-oauthlib>=0.7.0->google-auth-oauthlib<0.5,>=0.4.1->tensorboard>=2.2.0->stable-baselines3[extra]->finrl==0.3.4) (3.1.1)\n",
            "Collecting psycopg2-binary\n",
            "  Downloading psycopg2_binary-2.9.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.0 MB)\n",
            "\u001b[K     |████████████████████████████████| 3.0 MB 30.7 MB/s \n",
            "\u001b[?25hCollecting mock\n",
            "  Downloading mock-4.0.3-py3-none-any.whl (28 kB)\n",
            "Requirement already satisfied: multitasking>=0.0.7 in /usr/local/lib/python3.7/dist-packages (from yfinance->finrl==0.3.4) (0.0.10)\n",
            "Collecting requests>=2.18.4\n",
            "  Downloading requests-2.27.1-py2.py3-none-any.whl (63 kB)\n",
            "\u001b[K     |████████████████████████████████| 63 kB 2.1 MB/s \n",
            "\u001b[?25hCollecting lxml\n",
            "  Downloading lxml-4.7.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl (6.4 MB)\n",
            "\u001b[K     |████████████████████████████████| 6.4 MB 65.9 MB/s \n",
            "\u001b[?25hBuilding wheels for collected packages: finrl, elegantrl, pyfolio, empyrical, exchange-calendars, gputil, thriftpy2, gpustat\n",
            "  Building wheel for finrl (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for finrl: filename=finrl-0.3.4-py3-none-any.whl size=3885434 sha256=849cbf03841a5a022427fa9f806d06b3e94a6b1b24c083a41ea6f47445b938d8\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-pv4yf2kc/wheels/17/ff/bd/1bc602a0352762b0b24041b88536d803ae343ed0a711fcf55e\n",
            "  Building wheel for elegantrl (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for elegantrl: filename=elegantrl-0.3.3-py3-none-any.whl size=188472 sha256=8d5083e1d626c2ef812b814b40640e39b5018c862373497d500b55728f0fb8a3\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-pv4yf2kc/wheels/99/85/5e/86cb3a9f47adfca5e248295e93113e1b298d60883126d62c84\n",
            "  Building wheel for pyfolio (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for pyfolio: filename=pyfolio-0.9.2+75.g4b901f6-py3-none-any.whl size=75774 sha256=c4497ace077e94d44cf5ac597e917a70823257583d7dac76152d009c98bda297\n",
            "  Stored in directory: /tmp/pip-ephem-wheel-cache-pv4yf2kc/wheels/ef/09/e5/2c1bf37c050d22557c080deb1be986d06424627c04aeca19b9\n",
            "  Building wheel for empyrical (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for empyrical: filename=empyrical-0.5.5-py3-none-any.whl size=39780 sha256=ae4a57d940f20813f523a30c1de536b1f2531cac23a5de0b0bf37a9d3fa12015\n",
            "  Stored in directory: /root/.cache/pip/wheels/d9/91/4b/654fcff57477efcf149eaca236da2fce991526cbab431bf312\n",
            "  Building wheel for exchange-calendars (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for exchange-calendars: filename=exchange_calendars-3.5-py3-none-any.whl size=179486 sha256=043fd7e4bfa797afe79a9eded1762c9d4543807b9c192f2d0d99df42c3c7b2ce\n",
            "  Stored in directory: /root/.cache/pip/wheels/69/21/43/b6ae2605dd767f6cd5a5b0b70c93a9a75823e44b3ccb92bce7\n",
            "  Building wheel for gputil (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for gputil: filename=GPUtil-1.4.0-py3-none-any.whl size=7411 sha256=7a9b6d994aaf299e7a3c73dbb8a98ede27aa9199340077bd7571f3f07d6d425b\n",
            "  Stored in directory: /root/.cache/pip/wheels/6e/f8/83/534c52482d6da64622ddbf72cd93c35d2ef2881b78fd08ff0c\n",
            "  Building wheel for thriftpy2 (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for thriftpy2: filename=thriftpy2-0.4.14-cp37-cp37m-linux_x86_64.whl size=944197 sha256=e3ccabc57c0d1511e6e87f870d8941748f3af10e1e9b00010db3a0692d48165d\n",
            "  Stored in directory: /root/.cache/pip/wheels/2a/f5/49/9c0d851aa64b58db72883cf9393cc824d536bdf13f5c83cff4\n",
            "  Building wheel for gpustat (setup.py) ... \u001b[?25l\u001b[?25hdone\n",
            "  Created wheel for gpustat: filename=gpustat-1.0.0b1-py3-none-any.whl size=15979 sha256=c470a062e2c777d4121d6f451cf0224bc94b2ac7043e66724f194cc1bed87289\n",
            "  Stored in directory: /root/.cache/pip/wheels/1a/16/e2/3e2437fba4c4b6a97a97bd96fce5d14e66cff5c4966fb1cc8c\n",
            "Successfully built finrl elegantrl pyfolio empyrical exchange-calendars gputil thriftpy2 gpustat\n",
            "Installing collected packages: requests, multidict, frozenlist, yarl, lxml, deprecated, asynctest, async-timeout, aiosignal, redis, pyyaml, pycares, ply, platformdirs, opencensus-context, msgpack, hiredis, distlib, blessed, aiohttp, websockets, websocket-client, virtualenv, thriftpy2, tensorboardX, stable-baselines3, ray, pymysql, pyluach, pybullet, py-spy, psycopg2-binary, opencensus, nodeenv, mock, identify, gpustat, empyrical, cryptography, colorful, cfgv, box2d-py, aioredis, aiohttp-cors, aiodns, yfinance, wrds, stockstats, pyfolio, pre-commit, lz4, jqdatasdk, gputil, exchange-calendars, elegantrl, ccxt, alpaca-trade-api, finrl\n",
            "  Attempting uninstall: requests\n",
            "    Found existing installation: requests 2.23.0\n",
            "    Uninstalling requests-2.23.0:\n",
            "      Successfully uninstalled requests-2.23.0\n",
            "  Attempting uninstall: lxml\n",
            "    Found existing installation: lxml 4.2.6\n",
            "    Uninstalling lxml-4.2.6:\n",
            "      Successfully uninstalled lxml-4.2.6\n",
            "  Attempting uninstall: pyyaml\n",
            "    Found existing installation: PyYAML 3.13\n",
            "    Uninstalling PyYAML-3.13:\n",
            "      Successfully uninstalled PyYAML-3.13\n",
            "  Attempting uninstall: msgpack\n",
            "    Found existing installation: msgpack 1.0.3\n",
            "    Uninstalling msgpack-1.0.3:\n",
            "      Successfully uninstalled msgpack-1.0.3\n",
            "\u001b[31mERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.\n",
            "google-colab 1.0.0 requires requests~=2.23.0, but you have requests 2.27.1 which is incompatible.\n",
            "datascience 0.10.6 requires folium==0.2.1, but you have folium 0.8.3 which is incompatible.\u001b[0m\n",
            "Successfully installed aiodns-3.0.0 aiohttp-3.8.1 aiohttp-cors-0.7.0 aioredis-1.3.1 aiosignal-1.2.0 alpaca-trade-api-1.2.3 async-timeout-4.0.2 asynctest-0.13.0 blessed-1.19.0 box2d-py-2.3.8 ccxt-1.67.31 cfgv-3.3.1 colorful-0.5.4 cryptography-36.0.1 deprecated-1.2.13 distlib-0.3.4 elegantrl-0.3.3 empyrical-0.5.5 exchange-calendars-3.5 finrl-0.3.4 frozenlist-1.2.0 gpustat-1.0.0b1 gputil-1.4.0 hiredis-2.0.0 identify-2.4.3 jqdatasdk-1.8.10 lxml-4.7.1 lz4-3.1.10 mock-4.0.3 msgpack-1.0.2 multidict-5.2.0 nodeenv-1.6.0 opencensus-0.8.0 opencensus-context-0.1.2 platformdirs-2.4.1 ply-3.11 pre-commit-2.16.0 psycopg2-binary-2.9.3 py-spy-0.3.11 pybullet-3.2.1 pycares-4.1.2 pyfolio-0.9.2+75.g4b901f6 pyluach-1.3.0 pymysql-1.0.2 pyyaml-6.0 ray-1.9.2 redis-4.1.0 requests-2.27.1 stable-baselines3-1.3.0 stockstats-0.4.1 tensorboardX-2.4.1 thriftpy2-0.4.14 virtualenv-20.13.0 websocket-client-1.2.3 websockets-9.1 wrds-3.1.1 yarl-1.7.2 yfinance-0.1.69\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "osBHhVysOEzi"
      },
      "source": [
        "\n",
        "<a id='1.2'></a>\n",
        "## 2.2. Check if the additional packages needed are present, if not install them. \n",
        "* Yahoo Finance API\n",
        "* pandas\n",
        "* numpy\n",
        "* matplotlib\n",
        "* stockstats\n",
        "* OpenAI gym\n",
        "* stable-baselines\n",
        "* tensorflow\n",
        "* pyfolio"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "nGv01K8Sh1hn"
      },
      "source": [
        "<a id='1.3'></a>\n",
        "## 2.3. Import Packages"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lPqeTTwoh1hn",
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "outputId": "c850ef44-8e9a-4016-8012-5b7aaa759d3a"
      },
      "source": [
        "import pandas as pd\n",
        "import numpy as np\n",
        "import matplotlib\n",
        "import matplotlib.pyplot as plt\n",
        "# matplotlib.use('Agg')\n",
        "import datetime\n",
        "\n",
        "%matplotlib inline\n",
        "from finrl.apps import config\n",
        "from finrl.finrl_meta.preprocessor.yahoodownloader import YahooDownloader\n",
        "from finrl.finrl_meta.preprocessor.preprocessors import FeatureEngineer, data_split\n",
        "from finrl.finrl_meta.env_stock_trading.env_stocktrading import StockTradingEnv\n",
        "from finrl.drl_agents.stablebaselines3.models import DRLAgent\n",
        "from finrl.plot import backtest_stats, backtest_plot, get_daily_return, get_baseline\n",
        "\n",
        "from pprint import pprint\n",
        "\n",
        "import sys\n",
        "sys.path.append(\"../FinRL-Library\")\n",
        "\n",
        "import itertools"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/pyfolio/pos.py:27: UserWarning: Module \"zipline.assets\" not found; multipliers will not be applied to position notionals.\n",
            "  'Module \"zipline.assets\" not found; multipliers will not be applied'\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "T2owTj985RW4"
      },
      "source": [
        "<a id='1.4'></a>\n",
        "## 2.4. Create Folders"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "w9A8CN5R5PuZ"
      },
      "source": [
        "import os\n",
        "if not os.path.exists(\"./\" + config.DATA_SAVE_DIR):\n",
        "    os.makedirs(\"./\" + config.DATA_SAVE_DIR)\n",
        "if not os.path.exists(\"./\" + config.TRAINED_MODEL_DIR):\n",
        "    os.makedirs(\"./\" + config.TRAINED_MODEL_DIR)\n",
        "if not os.path.exists(\"./\" + config.TENSORBOARD_LOG_DIR):\n",
        "    os.makedirs(\"./\" + config.TENSORBOARD_LOG_DIR)\n",
        "if not os.path.exists(\"./\" + config.RESULTS_DIR):\n",
        "    os.makedirs(\"./\" + config.RESULTS_DIR)"
      ],
      "execution_count": 3,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "A289rQWMh1hq"
      },
      "source": [
        "<a id='2'></a>\n",
        "# Part 3. Download Stock Data from Yahoo Finance\n",
        "Yahoo Finance is a website that provides stock data, financial news, financial reports, etc. All the data provided by Yahoo Finance is free.\n",
        "* FinRL uses a class **YahooDownloader** to fetch data from Yahoo Finance API\n",
        "* Call Limit: Using the Public API (without authentication), you are limited to 2,000 requests per hour per IP (or up to a total of 48,000 requests a day).\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "NPeQ7iS-LoMm"
      },
      "source": [
        "\n",
        "\n",
        "-----\n",
        "class YahooDownloader:\n",
        "    Provides methods for retrieving daily stock data from\n",
        "    Yahoo Finance API\n",
        "\n",
        "    Attributes\n",
        "    ----------\n",
        "        start_date : str\n",
        "            start date of the data (modified from config.py)\n",
        "        end_date : str\n",
        "            end date of the data (modified from config.py)\n",
        "        ticker_list : list\n",
        "            a list of stock tickers (modified from config.py)\n",
        "\n",
        "    Methods\n",
        "    -------\n",
        "    fetch_data()\n",
        "        Fetches data from yahoo API\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "id": "h3XJnvrbLp-C",
        "outputId": "92bb3add-5dc3-409a-e8f1-11990934e994"
      },
      "source": [
        "# from config.py start_date is a string\n",
        "config.START_DATE"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            },
            "text/plain": [
              "'2009-01-01'"
            ]
          },
          "metadata": {},
          "execution_count": 4
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 35
        },
        "id": "FUnY8WEfLq3C",
        "outputId": "83391be5-cd6c-4576-d3ea-fb3f8b8c78ce"
      },
      "source": [
        "# from config.py end_date is a string\n",
        "config.END_DATE"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "application/vnd.google.colaboratory.intrinsic+json": {
              "type": "string"
            },
            "text/plain": [
              "'2021-10-31'"
            ]
          },
          "metadata": {},
          "execution_count": 5
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "JzqRRTOX6aFu",
        "outputId": "af56fb33-c833-4338-bd93-b415e5027a73"
      },
      "source": [
        "print(config.DOW_30_TICKER)"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "['AXP', 'AMGN', 'AAPL', 'BA', 'CAT', 'CSCO', 'CVX', 'GS', 'HD', 'HON', 'IBM', 'INTC', 'JNJ', 'KO', 'JPM', 'MCD', 'MMM', 'MRK', 'MSFT', 'NKE', 'PG', 'TRV', 'UNH', 'CRM', 'VZ', 'V', 'WBA', 'WMT', 'DIS', 'DOW']\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "yCKm4om-s9kE",
        "outputId": "ea64b198-6abf-4749-e108-f7cdcd227407"
      },
      "source": [
        "df = YahooDownloader(start_date = '2009-01-01',\n",
        "                     end_date = '2021-01-01',\n",
        "                     ticker_list = config.DOW_30_TICKER).fetch_data()"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "[*********************100%***********************]  1 of 1 completed\n",
            "Shape of DataFrame:  (88061, 8)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "CV3HrZHLh1hy",
        "outputId": "3374845e-e73a-4805-ee70-7532dd17d72f"
      },
      "source": [
        "df.shape"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/plain": [
              "(88061, 8)"
            ]
          },
          "metadata": {},
          "execution_count": 8
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "aBKF7sfV-Pi4",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "outputId": "c5f0a6c5-574d-43e0-a0a7-80bc875bd958"
      },
      "source": [
        "df.head()"
      ],
      "execution_count": 9,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-5b686ed4-0a1b-4a1f-a7db-41af9dafbdfd\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>tic</th>\n",
              "      <th>day</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615871</td>\n",
              "      <td>6547900</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.579438</td>\n",
              "      <td>10955700</td>\n",
              "      <td>AXP</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941101</td>\n",
              "      <td>7010200</td>\n",
              "      <td>BA</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475807</td>\n",
              "      <td>7117200</td>\n",
              "      <td>CAT</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-5b686ed4-0a1b-4a1f-a7db-41af9dafbdfd')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-5b686ed4-0a1b-4a1f-a7db-41af9dafbdfd button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-5b686ed4-0a1b-4a1f-a7db-41af9dafbdfd');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "         date       open       high        low      close     volume   tic  day\n",
              "0  2009-01-02   3.067143   3.251429   3.041429   2.778782  746015200  AAPL    4\n",
              "1  2009-01-02  58.590000  59.080002  57.750000  45.615871    6547900  AMGN    4\n",
              "2  2009-01-02  18.570000  19.520000  18.400000  15.579438   10955700   AXP    4\n",
              "3  2009-01-02  42.799999  45.560001  42.779999  33.941101    7010200    BA    4\n",
              "4  2009-01-02  44.910000  46.980000  44.709999  32.475807    7117200   CAT    4"
            ]
          },
          "metadata": {},
          "execution_count": 9
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QRWscKiPXXnj"
      },
      "source": [
        "df['date'] = pd.to_datetime(df['date'],format='%Y-%m-%d')"
      ],
      "execution_count": 10,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 206
        },
        "id": "4hYkeaPiICHS",
        "outputId": "57610cf0-7928-4b5c-b64c-8081ca058a50"
      },
      "source": [
        "df.sort_values(['date','tic'],ignore_index=True).head()"
      ],
      "execution_count": 11,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-70224b47-52b2-4a55-a616-d82fb62a9d94\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>tic</th>\n",
              "      <th>day</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615871</td>\n",
              "      <td>6547900</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.579438</td>\n",
              "      <td>10955700</td>\n",
              "      <td>AXP</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941101</td>\n",
              "      <td>7010200</td>\n",
              "      <td>BA</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475807</td>\n",
              "      <td>7117200</td>\n",
              "      <td>CAT</td>\n",
              "      <td>4</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-70224b47-52b2-4a55-a616-d82fb62a9d94')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-70224b47-52b2-4a55-a616-d82fb62a9d94 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-70224b47-52b2-4a55-a616-d82fb62a9d94');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date       open       high        low      close     volume   tic  day\n",
              "0 2009-01-02   3.067143   3.251429   3.041429   2.778782  746015200  AAPL    4\n",
              "1 2009-01-02  58.590000  59.080002  57.750000  45.615871    6547900  AMGN    4\n",
              "2 2009-01-02  18.570000  19.520000  18.400000  15.579438   10955700   AXP    4\n",
              "3 2009-01-02  42.799999  45.560001  42.779999  33.941101    7010200    BA    4\n",
              "4 2009-01-02  44.910000  46.980000  44.709999  32.475807    7117200   CAT    4"
            ]
          },
          "metadata": {},
          "execution_count": 11
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uqC6c40Zh1iH"
      },
      "source": [
        "# Part 4: Preprocess fundamental data\n",
        "- Import finanical data downloaded from Compustat via WRDS(Wharton Research Data Service)\n",
        "- Preprocess the dataset and calculate financial ratios\n",
        "- Add those ratios to the price data preprocessed in Part 3\n",
        "- Calculate price-related ratios such as P/E and P/B"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VbXEllD2oROq"
      },
      "source": [
        "## 4-1 Import the financial data"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "PmKP-1ii3RLS",
        "outputId": "00948eb6-4a1f-4aac-e789-92a58a87380c"
      },
      "source": [
        "# Import fundamental data from my GitHub repository\n",
        "url = 'https://raw.githubusercontent.com/mariko-sawada/FinRL_with_fundamental_data/main/dow_30_fundamental_wrds.csv'\n",
        "\n",
        "fund = pd.read_csv(url)"
      ],
      "execution_count": 12,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/IPython/core/interactiveshell.py:2718: DtypeWarning: Columns (16,25) have mixed types.Specify dtype option on import or set low_memory=False.\n",
            "  interactivity=interactivity, compiler=compiler, result=result)\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 473
        },
        "id": "Tslhs_O5pOTL",
        "outputId": "3f6b09d7-ae03-4c90-8cc8-996c9651c8f0"
      },
      "source": [
        "# Check the imported dataset\n",
        "fund.head()"
      ],
      "execution_count": 13,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-23eee1e7-6efa-4efe-bbf9-618c3547c24b\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>gvkey</th>\n",
              "      <th>datadate</th>\n",
              "      <th>fyearq</th>\n",
              "      <th>fqtr</th>\n",
              "      <th>fyr</th>\n",
              "      <th>indfmt</th>\n",
              "      <th>consol</th>\n",
              "      <th>popsrc</th>\n",
              "      <th>datafmt</th>\n",
              "      <th>tic</th>\n",
              "      <th>conm</th>\n",
              "      <th>acctchgq</th>\n",
              "      <th>acctstdq</th>\n",
              "      <th>adrrq</th>\n",
              "      <th>ajexq</th>\n",
              "      <th>ajpq</th>\n",
              "      <th>bsprq</th>\n",
              "      <th>compstq</th>\n",
              "      <th>curcdq</th>\n",
              "      <th>curncdq</th>\n",
              "      <th>currtrq</th>\n",
              "      <th>curuscnq</th>\n",
              "      <th>datacqtr</th>\n",
              "      <th>datafqtr</th>\n",
              "      <th>finalq</th>\n",
              "      <th>ogmq</th>\n",
              "      <th>rp</th>\n",
              "      <th>scfq</th>\n",
              "      <th>srcq</th>\n",
              "      <th>staltq</th>\n",
              "      <th>updq</th>\n",
              "      <th>apdedateq</th>\n",
              "      <th>fdateq</th>\n",
              "      <th>pdateq</th>\n",
              "      <th>rdq</th>\n",
              "      <th>acchgq</th>\n",
              "      <th>acomincq</th>\n",
              "      <th>acoq</th>\n",
              "      <th>actq</th>\n",
              "      <th>altoq</th>\n",
              "      <th>...</th>\n",
              "      <th>uspiy</th>\n",
              "      <th>ustdncy</th>\n",
              "      <th>usubdvpy</th>\n",
              "      <th>utfdocy</th>\n",
              "      <th>utfoscy</th>\n",
              "      <th>utmey</th>\n",
              "      <th>uwkcapcy</th>\n",
              "      <th>wcapchy</th>\n",
              "      <th>wcapcy</th>\n",
              "      <th>wday</th>\n",
              "      <th>wddy</th>\n",
              "      <th>wdepsy</th>\n",
              "      <th>wdpy</th>\n",
              "      <th>xidocy</th>\n",
              "      <th>xidoy</th>\n",
              "      <th>xinty</th>\n",
              "      <th>xiy</th>\n",
              "      <th>xopry</th>\n",
              "      <th>xoptdqpy</th>\n",
              "      <th>xoptdy</th>\n",
              "      <th>xoptepsqpy</th>\n",
              "      <th>xoptepsy</th>\n",
              "      <th>xoptqpy</th>\n",
              "      <th>xopty</th>\n",
              "      <th>xrdy</th>\n",
              "      <th>xsgay</th>\n",
              "      <th>exchg</th>\n",
              "      <th>costat</th>\n",
              "      <th>cshtrq</th>\n",
              "      <th>dvpspq</th>\n",
              "      <th>dvpsxq</th>\n",
              "      <th>mkvaltq</th>\n",
              "      <th>prccq</th>\n",
              "      <th>prchq</th>\n",
              "      <th>prclq</th>\n",
              "      <th>adjex</th>\n",
              "      <th>ggroup</th>\n",
              "      <th>gind</th>\n",
              "      <th>gsector</th>\n",
              "      <th>gsubind</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>1447</td>\n",
              "      <td>19990630</td>\n",
              "      <td>1999</td>\n",
              "      <td>2</td>\n",
              "      <td>12</td>\n",
              "      <td>INDL</td>\n",
              "      <td>C</td>\n",
              "      <td>D</td>\n",
              "      <td>STD</td>\n",
              "      <td>AXP</td>\n",
              "      <td>AMERICAN EXPRESS CO</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>GB</td>\n",
              "      <td>NaN</td>\n",
              "      <td>USD</td>\n",
              "      <td>USD</td>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1999Q2</td>\n",
              "      <td>1999Q2</td>\n",
              "      <td>Y</td>\n",
              "      <td>NaN</td>\n",
              "      <td>Q</td>\n",
              "      <td>7.0</td>\n",
              "      <td>5</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>19990726.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>9125.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>11</td>\n",
              "      <td>A</td>\n",
              "      <td>106125400.0</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>130.1250</td>\n",
              "      <td>142.6250</td>\n",
              "      <td>114.5000</td>\n",
              "      <td>3.0</td>\n",
              "      <td>4020</td>\n",
              "      <td>402020</td>\n",
              "      <td>40</td>\n",
              "      <td>40202010</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>1447</td>\n",
              "      <td>19990930</td>\n",
              "      <td>1999</td>\n",
              "      <td>3</td>\n",
              "      <td>12</td>\n",
              "      <td>INDL</td>\n",
              "      <td>C</td>\n",
              "      <td>D</td>\n",
              "      <td>STD</td>\n",
              "      <td>AXP</td>\n",
              "      <td>AMERICAN EXPRESS CO</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>GB</td>\n",
              "      <td>NaN</td>\n",
              "      <td>USD</td>\n",
              "      <td>USD</td>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1999Q3</td>\n",
              "      <td>1999Q3</td>\n",
              "      <td>Y</td>\n",
              "      <td>NaN</td>\n",
              "      <td>Q</td>\n",
              "      <td>7.0</td>\n",
              "      <td>5</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>19991025.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>13803.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>11</td>\n",
              "      <td>A</td>\n",
              "      <td>121724600.0</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.000</td>\n",
              "      <td>NaN</td>\n",
              "      <td>135.0000</td>\n",
              "      <td>150.6250</td>\n",
              "      <td>121.8750</td>\n",
              "      <td>3.0</td>\n",
              "      <td>4020</td>\n",
              "      <td>402020</td>\n",
              "      <td>40</td>\n",
              "      <td>40202010</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>1447</td>\n",
              "      <td>19991231</td>\n",
              "      <td>1999</td>\n",
              "      <td>4</td>\n",
              "      <td>12</td>\n",
              "      <td>INDL</td>\n",
              "      <td>C</td>\n",
              "      <td>D</td>\n",
              "      <td>STD</td>\n",
              "      <td>AXP</td>\n",
              "      <td>AMERICAN EXPRESS CO</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>GB</td>\n",
              "      <td>NaN</td>\n",
              "      <td>USD</td>\n",
              "      <td>USD</td>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1999Q4</td>\n",
              "      <td>1999Q4</td>\n",
              "      <td>Y</td>\n",
              "      <td>NaN</td>\n",
              "      <td>Q</td>\n",
              "      <td>7.0</td>\n",
              "      <td>53</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>20000124.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>18967.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>11</td>\n",
              "      <td>A</td>\n",
              "      <td>126218100.0</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>166.2500</td>\n",
              "      <td>168.8750</td>\n",
              "      <td>130.2500</td>\n",
              "      <td>3.0</td>\n",
              "      <td>4020</td>\n",
              "      <td>402020</td>\n",
              "      <td>40</td>\n",
              "      <td>40202010</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>1447</td>\n",
              "      <td>20000331</td>\n",
              "      <td>2000</td>\n",
              "      <td>1</td>\n",
              "      <td>12</td>\n",
              "      <td>INDL</td>\n",
              "      <td>C</td>\n",
              "      <td>D</td>\n",
              "      <td>STD</td>\n",
              "      <td>AXP</td>\n",
              "      <td>AMERICAN EXPRESS CO</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3.0</td>\n",
              "      <td>3.0</td>\n",
              "      <td>GB</td>\n",
              "      <td>NaN</td>\n",
              "      <td>USD</td>\n",
              "      <td>USD</td>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>2000Q1</td>\n",
              "      <td>2000Q1</td>\n",
              "      <td>Y</td>\n",
              "      <td>NaN</td>\n",
              "      <td>Q</td>\n",
              "      <td>7.0</td>\n",
              "      <td>5</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>20000424.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>5101.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>11</td>\n",
              "      <td>A</td>\n",
              "      <td>167224700.0</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>148.9375</td>\n",
              "      <td>169.5000</td>\n",
              "      <td>119.5000</td>\n",
              "      <td>3.0</td>\n",
              "      <td>4020</td>\n",
              "      <td>402020</td>\n",
              "      <td>40</td>\n",
              "      <td>40202010</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>1447</td>\n",
              "      <td>20000630</td>\n",
              "      <td>2000</td>\n",
              "      <td>2</td>\n",
              "      <td>12</td>\n",
              "      <td>INDL</td>\n",
              "      <td>C</td>\n",
              "      <td>D</td>\n",
              "      <td>STD</td>\n",
              "      <td>AXP</td>\n",
              "      <td>AMERICAN EXPRESS CO</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>1.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>GB</td>\n",
              "      <td>NaN</td>\n",
              "      <td>USD</td>\n",
              "      <td>USD</td>\n",
              "      <td>1.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>2000Q2</td>\n",
              "      <td>2000Q2</td>\n",
              "      <td>Y</td>\n",
              "      <td>NaN</td>\n",
              "      <td>Q</td>\n",
              "      <td>7.0</td>\n",
              "      <td>5</td>\n",
              "      <td>NaN</td>\n",
              "      <td>3</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>20000724.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>...</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.0</td>\n",
              "      <td>10425.0</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>11</td>\n",
              "      <td>A</td>\n",
              "      <td>325319600.0</td>\n",
              "      <td>0.080</td>\n",
              "      <td>0.080</td>\n",
              "      <td>NaN</td>\n",
              "      <td>52.1250</td>\n",
              "      <td>57.1875</td>\n",
              "      <td>43.9375</td>\n",
              "      <td>1.0</td>\n",
              "      <td>4020</td>\n",
              "      <td>402020</td>\n",
              "      <td>40</td>\n",
              "      <td>40202010</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "<p>5 rows × 647 columns</p>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-23eee1e7-6efa-4efe-bbf9-618c3547c24b')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-23eee1e7-6efa-4efe-bbf9-618c3547c24b button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-23eee1e7-6efa-4efe-bbf9-618c3547c24b');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "   gvkey  datadate  fyearq  fqtr  fyr  ... adjex ggroup    gind gsector   gsubind\n",
              "0   1447  19990630    1999     2   12  ...   3.0   4020  402020      40  40202010\n",
              "1   1447  19990930    1999     3   12  ...   3.0   4020  402020      40  40202010\n",
              "2   1447  19991231    1999     4   12  ...   3.0   4020  402020      40  40202010\n",
              "3   1447  20000331    2000     1   12  ...   3.0   4020  402020      40  40202010\n",
              "4   1447  20000630    2000     2   12  ...   1.0   4020  402020      40  40202010\n",
              "\n",
              "[5 rows x 647 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 13
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9yk1dHTYogEP"
      },
      "source": [
        "## 4-2 Specify items needed to calculate financial ratios\n",
        "- To know more about the data description of the dataset, please check WRDS's website(https://wrds-www.wharton.upenn.edu/). Login will be required."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "CD0kFC7Ap02K"
      },
      "source": [
        "# List items that are used to calculate financial ratios\n",
        "\n",
        "items = [\n",
        "    'datadate', # Date\n",
        "    'tic', # Ticker\n",
        "    'oiadpq', # Quarterly operating income\n",
        "    'revtq', # Quartely revenue\n",
        "    'niq', # Quartely net income\n",
        "    'atq', # Total asset\n",
        "    'teqq', # Shareholder's equity\n",
        "    'epspiy', # EPS(Basic) incl. Extraordinary items\n",
        "    'ceqq', # Common Equity\n",
        "    'cshoq', # Common Shares Outstanding\n",
        "    'dvpspq', # Dividends per share\n",
        "    'actq', # Current assets\n",
        "    'lctq', # Current liabilities\n",
        "    'cheq', # Cash & Equivalent\n",
        "    'rectq', # Recievalbles\n",
        "    'cogsq', # Cost of  Goods Sold\n",
        "    'invtq', # Inventories\n",
        "    'apq',# Account payable\n",
        "    'dlttq', # Long term debt\n",
        "    'dlcq', # Debt in current liabilites\n",
        "    'ltq' # Liabilities   \n",
        "]\n",
        "\n",
        "# Omit items that will not be used\n",
        "fund_data = fund[items]"
      ],
      "execution_count": 14,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "jE7UNYtIqFkv"
      },
      "source": [
        "# Rename column names for the sake of readability\n",
        "fund_data = fund_data.rename(columns={\n",
        "    'datadate':'date', # Date\n",
        "    'oiadpq':'op_inc_q', # Quarterly operating income\n",
        "    'revtq':'rev_q', # Quartely revenue\n",
        "    'niq':'net_inc_q', # Quartely net income\n",
        "    'atq':'tot_assets', # Assets\n",
        "    'teqq':'sh_equity', # Shareholder's equity\n",
        "    'epspiy':'eps_incl_ex', # EPS(Basic) incl. Extraordinary items\n",
        "    'ceqq':'com_eq', # Common Equity\n",
        "    'cshoq':'sh_outstanding', # Common Shares Outstanding\n",
        "    'dvpspq':'div_per_sh', # Dividends per share\n",
        "    'actq':'cur_assets', # Current assets\n",
        "    'lctq':'cur_liabilities', # Current liabilities\n",
        "    'cheq':'cash_eq', # Cash & Equivalent\n",
        "    'rectq':'receivables', # Receivalbles\n",
        "    'cogsq':'cogs_q', # Cost of  Goods Sold\n",
        "    'invtq':'inventories', # Inventories\n",
        "    'apq': 'payables',# Account payable\n",
        "    'dlttq':'long_debt', # Long term debt\n",
        "    'dlcq':'short_debt', # Debt in current liabilites\n",
        "    'ltq':'tot_liabilities' # Liabilities   \n",
        "})"
      ],
      "execution_count": 15,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 270
        },
        "id": "A0sszApfqO6D",
        "outputId": "e495a2b8-31e8-4ec9-bbfe-9d42dc53a0c2"
      },
      "source": [
        "# Check the data\n",
        "fund_data.head()"
      ],
      "execution_count": 16,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-1fcce12a-d34a-4c20-834d-ec447ab92af6\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>op_inc_q</th>\n",
              "      <th>rev_q</th>\n",
              "      <th>net_inc_q</th>\n",
              "      <th>tot_assets</th>\n",
              "      <th>sh_equity</th>\n",
              "      <th>eps_incl_ex</th>\n",
              "      <th>com_eq</th>\n",
              "      <th>sh_outstanding</th>\n",
              "      <th>div_per_sh</th>\n",
              "      <th>cur_assets</th>\n",
              "      <th>cur_liabilities</th>\n",
              "      <th>cash_eq</th>\n",
              "      <th>receivables</th>\n",
              "      <th>cogs_q</th>\n",
              "      <th>inventories</th>\n",
              "      <th>payables</th>\n",
              "      <th>long_debt</th>\n",
              "      <th>short_debt</th>\n",
              "      <th>tot_liabilities</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>19990630</td>\n",
              "      <td>AXP</td>\n",
              "      <td>896.0</td>\n",
              "      <td>5564.0</td>\n",
              "      <td>646.0</td>\n",
              "      <td>132452.0</td>\n",
              "      <td>9762.0</td>\n",
              "      <td>2.73</td>\n",
              "      <td>9762.0</td>\n",
              "      <td>449.0</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>6096.0</td>\n",
              "      <td>46774.0</td>\n",
              "      <td>4668.0</td>\n",
              "      <td>448.0</td>\n",
              "      <td>22282.0</td>\n",
              "      <td>7005.0</td>\n",
              "      <td>24785.0</td>\n",
              "      <td>122690.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>19990930</td>\n",
              "      <td>AXP</td>\n",
              "      <td>906.0</td>\n",
              "      <td>5584.0</td>\n",
              "      <td>648.0</td>\n",
              "      <td>132616.0</td>\n",
              "      <td>9744.0</td>\n",
              "      <td>4.18</td>\n",
              "      <td>9744.0</td>\n",
              "      <td>447.6</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>5102.0</td>\n",
              "      <td>48827.0</td>\n",
              "      <td>4678.0</td>\n",
              "      <td>284.0</td>\n",
              "      <td>23587.0</td>\n",
              "      <td>6720.0</td>\n",
              "      <td>24683.0</td>\n",
              "      <td>122872.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>19991231</td>\n",
              "      <td>AXP</td>\n",
              "      <td>845.0</td>\n",
              "      <td>6009.0</td>\n",
              "      <td>606.0</td>\n",
              "      <td>148517.0</td>\n",
              "      <td>10095.0</td>\n",
              "      <td>5.54</td>\n",
              "      <td>10095.0</td>\n",
              "      <td>446.9</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>10391.0</td>\n",
              "      <td>54033.0</td>\n",
              "      <td>5164.0</td>\n",
              "      <td>277.0</td>\n",
              "      <td>25719.0</td>\n",
              "      <td>4685.0</td>\n",
              "      <td>32437.0</td>\n",
              "      <td>138422.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>20000331</td>\n",
              "      <td>AXP</td>\n",
              "      <td>920.0</td>\n",
              "      <td>6021.0</td>\n",
              "      <td>656.0</td>\n",
              "      <td>150662.0</td>\n",
              "      <td>10253.0</td>\n",
              "      <td>1.48</td>\n",
              "      <td>10253.0</td>\n",
              "      <td>444.7</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>7425.0</td>\n",
              "      <td>53663.0</td>\n",
              "      <td>5101.0</td>\n",
              "      <td>315.0</td>\n",
              "      <td>26379.0</td>\n",
              "      <td>5670.0</td>\n",
              "      <td>29342.0</td>\n",
              "      <td>140409.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>20000630</td>\n",
              "      <td>AXP</td>\n",
              "      <td>1046.0</td>\n",
              "      <td>6370.0</td>\n",
              "      <td>740.0</td>\n",
              "      <td>148553.0</td>\n",
              "      <td>10509.0</td>\n",
              "      <td>1.05</td>\n",
              "      <td>10509.0</td>\n",
              "      <td>1333.0</td>\n",
              "      <td>0.080</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>6841.0</td>\n",
              "      <td>54286.0</td>\n",
              "      <td>5324.0</td>\n",
              "      <td>261.0</td>\n",
              "      <td>29536.0</td>\n",
              "      <td>5336.0</td>\n",
              "      <td>26170.0</td>\n",
              "      <td>138044.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-1fcce12a-d34a-4c20-834d-ec447ab92af6')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-1fcce12a-d34a-4c20-834d-ec447ab92af6 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-1fcce12a-d34a-4c20-834d-ec447ab92af6');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "       date  tic  op_inc_q  ...  long_debt  short_debt  tot_liabilities\n",
              "0  19990630  AXP     896.0  ...     7005.0     24785.0         122690.0\n",
              "1  19990930  AXP     906.0  ...     6720.0     24683.0         122872.0\n",
              "2  19991231  AXP     845.0  ...     4685.0     32437.0         138422.0\n",
              "3  20000331  AXP     920.0  ...     5670.0     29342.0         140409.0\n",
              "4  20000630  AXP    1046.0  ...     5336.0     26170.0         138044.0\n",
              "\n",
              "[5 rows x 21 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 16
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "xPvwtMQUqZdP"
      },
      "source": [
        "## 4-3 Calculate financial ratios\n",
        "- For items from Profit/Loss statements, we calculate LTM (Last Twelve Months) and use them to derive profitability related ratios such as Operating Maring and ROE. For items from balance sheets, we use the numbers on the day.\n",
        "- To check the definitions of the financial ratios calculated here, please refer to CFI's website: https://corporatefinanceinstitute.com/resources/knowledge/finance/financial-ratios/"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "cfWtEophqS33",
        "outputId": "2cacb38b-0780-49b8-d3d3-7a2baeca6928"
      },
      "source": [
        "# Calculate financial ratios\n",
        "date = pd.to_datetime(fund_data['date'],format='%Y%m%d')\n",
        "\n",
        "tic = fund_data['tic'].to_frame('tic')\n",
        "\n",
        "# Profitability ratios\n",
        "# Operating Margin\n",
        "OPM = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='OPM')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        OPM[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        OPM.iloc[i] = np.nan\n",
        "    else:\n",
        "        OPM.iloc[i] = np.sum(fund_data['op_inc_q'].iloc[i-3:i])/np.sum(fund_data['rev_q'].iloc[i-3:i])\n",
        "\n",
        "# Net Profit Margin        \n",
        "NPM = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='NPM')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        NPM[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        NPM.iloc[i] = np.nan\n",
        "    else:\n",
        "        NPM.iloc[i] = np.sum(fund_data['net_inc_q'].iloc[i-3:i])/np.sum(fund_data['rev_q'].iloc[i-3:i])\n",
        "\n",
        "# Return On Assets\n",
        "ROA = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='ROA')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        ROA[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        ROA.iloc[i] = np.nan\n",
        "    else:\n",
        "        ROA.iloc[i] = np.sum(fund_data['net_inc_q'].iloc[i-3:i])/fund_data['tot_assets'].iloc[i]\n",
        "\n",
        "# Return on Equity\n",
        "ROE = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='ROE')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        ROE[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        ROE.iloc[i] = np.nan\n",
        "    else:\n",
        "        ROE.iloc[i] = np.sum(fund_data['net_inc_q'].iloc[i-3:i])/fund_data['sh_equity'].iloc[i]        \n",
        "\n",
        "# For calculating valuation ratios in the next subpart, calculate per share items in advance\n",
        "# Earnings Per Share       \n",
        "EPS = fund_data['eps_incl_ex'].to_frame('EPS')\n",
        "\n",
        "# Book Per Share\n",
        "BPS = (fund_data['com_eq']/fund_data['sh_outstanding']).to_frame('BPS') # Need to check units\n",
        "\n",
        "#Dividend Per Share\n",
        "DPS = fund_data['div_per_sh'].to_frame('DPS')\n",
        "\n",
        "# Liquidity ratios\n",
        "# Current ratio\n",
        "cur_ratio = (fund_data['cur_assets']/fund_data['cur_liabilities']).to_frame('cur_ratio')\n",
        "\n",
        "# Quick ratio\n",
        "quick_ratio = ((fund_data['cash_eq'] + fund_data['receivables'] )/fund_data['cur_liabilities']).to_frame('quick_ratio')\n",
        "\n",
        "# Cash ratio\n",
        "cash_ratio = (fund_data['cash_eq']/fund_data['cur_liabilities']).to_frame('cash_ratio')\n",
        "\n",
        "\n",
        "# Efficiency ratios\n",
        "# Inventory turnover ratio\n",
        "inv_turnover = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='inv_turnover')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        inv_turnover[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        inv_turnover.iloc[i] = np.nan\n",
        "    else:\n",
        "        inv_turnover.iloc[i] = np.sum(fund_data['cogs_q'].iloc[i-3:i])/fund_data['inventories'].iloc[i]\n",
        "\n",
        "# Receivables turnover ratio       \n",
        "acc_rec_turnover = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='acc_rec_turnover')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        acc_rec_turnover[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        acc_rec_turnover.iloc[i] = np.nan\n",
        "    else:\n",
        "        acc_rec_turnover.iloc[i] = np.sum(fund_data['rev_q'].iloc[i-3:i])/fund_data['receivables'].iloc[i]\n",
        "\n",
        "# Payable turnover ratio\n",
        "acc_pay_turnover = pd.Series(np.empty(fund_data.shape[0],dtype=object),name='acc_pay_turnover')\n",
        "for i in range(0, fund_data.shape[0]):\n",
        "    if i-3 < 0:\n",
        "        acc_pay_turnover[i] = np.nan\n",
        "    elif fund_data.iloc[i,1] != fund_data.iloc[i-3,1]:\n",
        "        acc_pay_turnover.iloc[i] = np.nan\n",
        "    else:\n",
        "        acc_pay_turnover.iloc[i] = np.sum(fund_data['cogs_q'].iloc[i-3:i])/fund_data['payables'].iloc[i]\n",
        "        \n",
        "## Leverage financial ratios\n",
        "# Debt ratio\n",
        "debt_ratio = (fund_data['tot_liabilities']/fund_data['tot_assets']).to_frame('debt_ratio')\n",
        "\n",
        "# Debt to Equity ratio\n",
        "debt_to_equity = (fund_data['tot_liabilities']/fund_data['sh_equity']).to_frame('debt_to_equity')"
      ],
      "execution_count": 17,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stderr",
          "text": [
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:15: RuntimeWarning: divide by zero encountered in double_scalars\n",
            "  from ipykernel import kernelapp as app\n",
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:15: RuntimeWarning: invalid value encountered in double_scalars\n",
            "  from ipykernel import kernelapp as app\n",
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: RuntimeWarning: divide by zero encountered in double_scalars\n",
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:25: RuntimeWarning: invalid value encountered in double_scalars\n",
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:77: RuntimeWarning: divide by zero encountered in double_scalars\n",
            "/usr/local/lib/python3.7/dist-packages/ipykernel_launcher.py:77: RuntimeWarning: invalid value encountered in double_scalars\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "wwFVopRDqcby"
      },
      "source": [
        "# Create a dataframe that merges all the ratios\n",
        "ratios = pd.concat([date,tic,OPM,NPM,ROA,ROE,EPS,BPS,DPS,\n",
        "                    cur_ratio,quick_ratio,cash_ratio,inv_turnover,acc_rec_turnover,acc_pay_turnover,\n",
        "                   debt_ratio,debt_to_equity], axis=1)"
      ],
      "execution_count": 18,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "id": "Mvnw7izFsJcT",
        "outputId": "1b1807ff-ab6b-478d-8d9a-eb6a94b9ead0"
      },
      "source": [
        "# Check the ratio data\n",
        "ratios.head()"
      ],
      "execution_count": 19,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-15b1e3c9-a0cd-4ce4-9c5e-4904f79770d3\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>EPS</th>\n",
              "      <th>BPS</th>\n",
              "      <th>DPS</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>1999-06-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>2.73</td>\n",
              "      <td>21.741648</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.926298</td>\n",
              "      <td>12.568121</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>1999-09-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>4.18</td>\n",
              "      <td>21.769437</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.926525</td>\n",
              "      <td>12.610016</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>1999-12-31</td>\n",
              "      <td>AXP</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>5.54</td>\n",
              "      <td>22.588946</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>0.932028</td>\n",
              "      <td>13.711937</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2000-03-31</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.154281</td>\n",
              "      <td>0.110742</td>\n",
              "      <td>0.012611</td>\n",
              "      <td>0.185312</td>\n",
              "      <td>1.48</td>\n",
              "      <td>23.055993</td>\n",
              "      <td>0.225</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>46.0635</td>\n",
              "      <td>0.319717</td>\n",
              "      <td>0.550059</td>\n",
              "      <td>0.931947</td>\n",
              "      <td>13.694431</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2000-06-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.151641</td>\n",
              "      <td>0.108436</td>\n",
              "      <td>0.0128574</td>\n",
              "      <td>0.181749</td>\n",
              "      <td>1.05</td>\n",
              "      <td>7.883721</td>\n",
              "      <td>0.080</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>NaN</td>\n",
              "      <td>57.2529</td>\n",
              "      <td>0.324467</td>\n",
              "      <td>0.505925</td>\n",
              "      <td>0.929258</td>\n",
              "      <td>13.135788</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-15b1e3c9-a0cd-4ce4-9c5e-4904f79770d3')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-15b1e3c9-a0cd-4ce4-9c5e-4904f79770d3 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-15b1e3c9-a0cd-4ce4-9c5e-4904f79770d3');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date  tic       OPM  ... acc_pay_turnover debt_ratio debt_to_equity\n",
              "0 1999-06-30  AXP       NaN  ...              NaN   0.926298      12.568121\n",
              "1 1999-09-30  AXP       NaN  ...              NaN   0.926525      12.610016\n",
              "2 1999-12-31  AXP       NaN  ...              NaN   0.932028      13.711937\n",
              "3 2000-03-31  AXP  0.154281  ...         0.550059   0.931947      13.694431\n",
              "4 2000-06-30  AXP  0.151641  ...         0.505925   0.929258      13.135788\n",
              "\n",
              "[5 rows x 17 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 19
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AvG67ouguUKF",
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "outputId": "7499b69e-9c5a-40f6-82e5-308de61b9e6a"
      },
      "source": [
        "ratios.tail()"
      ],
      "execution_count": 20,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-753ed64f-1acb-4c0e-a4cb-17c60752837b\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>EPS</th>\n",
              "      <th>BPS</th>\n",
              "      <th>DPS</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2451</th>\n",
              "      <td>2020-03-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.667517</td>\n",
              "      <td>0.521213</td>\n",
              "      <td>0.129058</td>\n",
              "      <td>0.271736</td>\n",
              "      <td>2.85</td>\n",
              "      <td>13.647142</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.248714</td>\n",
              "      <td>1.140070</td>\n",
              "      <td>0.955150</td>\n",
              "      <td>inf</td>\n",
              "      <td>6.11635</td>\n",
              "      <td>2.69754</td>\n",
              "      <td>0.525062</td>\n",
              "      <td>1.105537</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2452</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>V</td>\n",
              "      <td>0.668385</td>\n",
              "      <td>0.519867</td>\n",
              "      <td>0.120448</td>\n",
              "      <td>0.264075</td>\n",
              "      <td>3.92</td>\n",
              "      <td>14.203947</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.553478</td>\n",
              "      <td>1.443292</td>\n",
              "      <td>1.221925</td>\n",
              "      <td>inf</td>\n",
              "      <td>5.06313</td>\n",
              "      <td>1.88951</td>\n",
              "      <td>0.543886</td>\n",
              "      <td>1.192433</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2453</th>\n",
              "      <td>2020-09-30</td>\n",
              "      <td>V</td>\n",
              "      <td>0.654464</td>\n",
              "      <td>0.52129</td>\n",
              "      <td>0.107873</td>\n",
              "      <td>0.241066</td>\n",
              "      <td>4.90</td>\n",
              "      <td>14.653484</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.905238</td>\n",
              "      <td>1.784838</td>\n",
              "      <td>1.579807</td>\n",
              "      <td>inf</td>\n",
              "      <td>5.62857</td>\n",
              "      <td>2.73037</td>\n",
              "      <td>0.552515</td>\n",
              "      <td>1.234714</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2454</th>\n",
              "      <td>2020-12-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.638994</td>\n",
              "      <td>0.480876</td>\n",
              "      <td>0.0944222</td>\n",
              "      <td>0.201545</td>\n",
              "      <td>1.42</td>\n",
              "      <td>15.908283</td>\n",
              "      <td>0.32</td>\n",
              "      <td>2.121065</td>\n",
              "      <td>1.969814</td>\n",
              "      <td>1.700081</td>\n",
              "      <td>inf</td>\n",
              "      <td>4.72531</td>\n",
              "      <td>2.34787</td>\n",
              "      <td>0.531507</td>\n",
              "      <td>1.134505</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2455</th>\n",
              "      <td>2021-03-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.640128</td>\n",
              "      <td>0.488704</td>\n",
              "      <td>0.0952179</td>\n",
              "      <td>0.202568</td>\n",
              "      <td>2.80</td>\n",
              "      <td>16.088525</td>\n",
              "      <td>0.32</td>\n",
              "      <td>2.116356</td>\n",
              "      <td>1.954292</td>\n",
              "      <td>1.700574</td>\n",
              "      <td>inf</td>\n",
              "      <td>4.84496</td>\n",
              "      <td>2.36736</td>\n",
              "      <td>0.529946</td>\n",
              "      <td>1.127414</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-753ed64f-1acb-4c0e-a4cb-17c60752837b')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-753ed64f-1acb-4c0e-a4cb-17c60752837b button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-753ed64f-1acb-4c0e-a4cb-17c60752837b');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "           date tic       OPM  ... acc_pay_turnover debt_ratio debt_to_equity\n",
              "2451 2020-03-31   V  0.667517  ...          2.69754   0.525062       1.105537\n",
              "2452 2020-06-30   V  0.668385  ...          1.88951   0.543886       1.192433\n",
              "2453 2020-09-30   V  0.654464  ...          2.73037   0.552515       1.234714\n",
              "2454 2020-12-31   V  0.638994  ...          2.34787   0.531507       1.134505\n",
              "2455 2021-03-31   V  0.640128  ...          2.36736   0.529946       1.127414\n",
              "\n",
              "[5 rows x 17 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 20
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JULhnNv8uaOB"
      },
      "source": [
        "## 4-4 Deal with NAs and infinite values\n",
        "- We replace N/A and infinite values with zero so that they can be recognized as a state"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nuKPlGe4sNzQ"
      },
      "source": [
        "# Replace NAs infinite values with zero\n",
        "final_ratios = ratios.copy()\n",
        "final_ratios = final_ratios.fillna(0)\n",
        "final_ratios = final_ratios.replace(np.inf,0)"
      ],
      "execution_count": 21,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "id": "wc_rvvm1sRDd",
        "outputId": "7177e91f-b1b7-4f1f-d2eb-8c6b42c9b109"
      },
      "source": [
        "final_ratios.head()"
      ],
      "execution_count": 22,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-4fa6b958-aae6-443e-99f3-54c930e526dd\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>EPS</th>\n",
              "      <th>BPS</th>\n",
              "      <th>DPS</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>1999-06-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>2.73</td>\n",
              "      <td>21.741648</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.926298</td>\n",
              "      <td>12.568121</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>1999-09-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>4.18</td>\n",
              "      <td>21.769437</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.926525</td>\n",
              "      <td>12.610016</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>1999-12-31</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>5.54</td>\n",
              "      <td>22.588946</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.932028</td>\n",
              "      <td>13.711937</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2000-03-31</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.154281</td>\n",
              "      <td>0.110742</td>\n",
              "      <td>0.012611</td>\n",
              "      <td>0.185312</td>\n",
              "      <td>1.48</td>\n",
              "      <td>23.055993</td>\n",
              "      <td>0.225</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>46.063492</td>\n",
              "      <td>0.319717</td>\n",
              "      <td>0.550059</td>\n",
              "      <td>0.931947</td>\n",
              "      <td>13.694431</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2000-06-30</td>\n",
              "      <td>AXP</td>\n",
              "      <td>0.151641</td>\n",
              "      <td>0.108436</td>\n",
              "      <td>0.012857</td>\n",
              "      <td>0.181749</td>\n",
              "      <td>1.05</td>\n",
              "      <td>7.883721</td>\n",
              "      <td>0.080</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>57.252874</td>\n",
              "      <td>0.324467</td>\n",
              "      <td>0.505925</td>\n",
              "      <td>0.929258</td>\n",
              "      <td>13.135788</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-4fa6b958-aae6-443e-99f3-54c930e526dd')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-4fa6b958-aae6-443e-99f3-54c930e526dd button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-4fa6b958-aae6-443e-99f3-54c930e526dd');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date  tic       OPM  ...  acc_pay_turnover  debt_ratio  debt_to_equity\n",
              "0 1999-06-30  AXP  0.000000  ...          0.000000    0.926298       12.568121\n",
              "1 1999-09-30  AXP  0.000000  ...          0.000000    0.926525       12.610016\n",
              "2 1999-12-31  AXP  0.000000  ...          0.000000    0.932028       13.711937\n",
              "3 2000-03-31  AXP  0.154281  ...          0.550059    0.931947       13.694431\n",
              "4 2000-06-30  AXP  0.151641  ...          0.505925    0.929258       13.135788\n",
              "\n",
              "[5 rows x 17 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 22
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "id": "RKwmRfs5sfra",
        "outputId": "b79f214e-7a2a-42bf-cebd-e478dec71d73"
      },
      "source": [
        "final_ratios.tail()"
      ],
      "execution_count": 23,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-0f554733-34c0-4827-a088-e7b0d2de7b1c\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>EPS</th>\n",
              "      <th>BPS</th>\n",
              "      <th>DPS</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2451</th>\n",
              "      <td>2020-03-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.667517</td>\n",
              "      <td>0.521213</td>\n",
              "      <td>0.129058</td>\n",
              "      <td>0.271736</td>\n",
              "      <td>2.85</td>\n",
              "      <td>13.647142</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.248714</td>\n",
              "      <td>1.140070</td>\n",
              "      <td>0.955150</td>\n",
              "      <td>0.0</td>\n",
              "      <td>6.116350</td>\n",
              "      <td>2.697537</td>\n",
              "      <td>0.525062</td>\n",
              "      <td>1.105537</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2452</th>\n",
              "      <td>2020-06-30</td>\n",
              "      <td>V</td>\n",
              "      <td>0.668385</td>\n",
              "      <td>0.519867</td>\n",
              "      <td>0.120448</td>\n",
              "      <td>0.264075</td>\n",
              "      <td>3.92</td>\n",
              "      <td>14.203947</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.553478</td>\n",
              "      <td>1.443292</td>\n",
              "      <td>1.221925</td>\n",
              "      <td>0.0</td>\n",
              "      <td>5.063131</td>\n",
              "      <td>1.889507</td>\n",
              "      <td>0.543886</td>\n",
              "      <td>1.192433</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2453</th>\n",
              "      <td>2020-09-30</td>\n",
              "      <td>V</td>\n",
              "      <td>0.654464</td>\n",
              "      <td>0.521290</td>\n",
              "      <td>0.107873</td>\n",
              "      <td>0.241066</td>\n",
              "      <td>4.90</td>\n",
              "      <td>14.653484</td>\n",
              "      <td>0.30</td>\n",
              "      <td>1.905238</td>\n",
              "      <td>1.784838</td>\n",
              "      <td>1.579807</td>\n",
              "      <td>0.0</td>\n",
              "      <td>5.628571</td>\n",
              "      <td>2.730366</td>\n",
              "      <td>0.552515</td>\n",
              "      <td>1.234714</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2454</th>\n",
              "      <td>2020-12-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.638994</td>\n",
              "      <td>0.480876</td>\n",
              "      <td>0.094422</td>\n",
              "      <td>0.201545</td>\n",
              "      <td>1.42</td>\n",
              "      <td>15.908283</td>\n",
              "      <td>0.32</td>\n",
              "      <td>2.121065</td>\n",
              "      <td>1.969814</td>\n",
              "      <td>1.700081</td>\n",
              "      <td>0.0</td>\n",
              "      <td>4.725314</td>\n",
              "      <td>2.347866</td>\n",
              "      <td>0.531507</td>\n",
              "      <td>1.134505</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2455</th>\n",
              "      <td>2021-03-31</td>\n",
              "      <td>V</td>\n",
              "      <td>0.640128</td>\n",
              "      <td>0.488704</td>\n",
              "      <td>0.095218</td>\n",
              "      <td>0.202568</td>\n",
              "      <td>2.80</td>\n",
              "      <td>16.088525</td>\n",
              "      <td>0.32</td>\n",
              "      <td>2.116356</td>\n",
              "      <td>1.954292</td>\n",
              "      <td>1.700574</td>\n",
              "      <td>0.0</td>\n",
              "      <td>4.844961</td>\n",
              "      <td>2.367357</td>\n",
              "      <td>0.529946</td>\n",
              "      <td>1.127414</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-0f554733-34c0-4827-a088-e7b0d2de7b1c')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-0f554733-34c0-4827-a088-e7b0d2de7b1c button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-0f554733-34c0-4827-a088-e7b0d2de7b1c');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "           date tic       OPM  ...  acc_pay_turnover  debt_ratio  debt_to_equity\n",
              "2451 2020-03-31   V  0.667517  ...          2.697537    0.525062        1.105537\n",
              "2452 2020-06-30   V  0.668385  ...          1.889507    0.543886        1.192433\n",
              "2453 2020-09-30   V  0.654464  ...          2.730366    0.552515        1.234714\n",
              "2454 2020-12-31   V  0.638994  ...          2.347866    0.531507        1.134505\n",
              "2455 2021-03-31   V  0.640128  ...          2.367357    0.529946        1.127414\n",
              "\n",
              "[5 rows x 17 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 23
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "66kjM0lhu91F"
      },
      "source": [
        "## 4-5 Merge stock price data and ratios into one dataframe\n",
        "- Merge the price dataframe preprocessed in Part 3 and the ratio dataframe created in this part\n",
        "- Since the prices are daily and ratios are quartely, we have NAs in the ratio columns after merging the two dataframes. We deal with this by backfilling the ratios."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Kixon2tR3RLT"
      },
      "source": [
        "list_ticker = df[\"tic\"].unique().tolist()\n",
        "list_date = list(pd.date_range(df['date'].min(),df['date'].max()))\n",
        "combination = list(itertools.product(list_date,list_ticker))\n",
        "\n",
        "# Merge stock price data and ratios into one dataframe\n",
        "processed_full = pd.DataFrame(combination,columns=[\"date\",\"tic\"]).merge(df,on=[\"date\",\"tic\"],how=\"left\")\n",
        "processed_full = processed_full.merge(final_ratios,how='left',on=['date','tic'])\n",
        "processed_full = processed_full.sort_values(['tic','date'])\n",
        "\n",
        "# Backfill the ratio data to make them daily\n",
        "processed_full = processed_full.bfill(axis='rows')\n"
      ],
      "execution_count": 24,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "CGU69Ccfw_bR"
      },
      "source": [
        "## 4-6 Calculate market valuation ratios using daily stock price data "
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "EhiYLZPBVZNW"
      },
      "source": [
        "# Calculate P/E, P/B and dividend yield using daily closing price\n",
        "processed_full['PE'] = processed_full['close']/processed_full['EPS']\n",
        "processed_full['PB'] = processed_full['close']/processed_full['BPS']\n",
        "processed_full['Div_yield'] = processed_full['DPS']/processed_full['close']\n",
        "\n",
        "# Drop per share items used for the above calculation\n",
        "processed_full = processed_full.drop(columns=['day','EPS','BPS','DPS'])\n",
        "# Replace NAs infinite values with zero\n",
        "processed_full = processed_full.copy()\n",
        "processed_full = processed_full.fillna(0)\n",
        "processed_full = processed_full.replace(np.inf,0)"
      ],
      "execution_count": 25,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 0
        },
        "id": "grvhGJJII3Xn",
        "outputId": "028731bd-dd0a-4c1e-ff31-20ae12b31e3a"
      },
      "source": [
        "# Check the final data\n",
        "processed_full.sort_values(['date','tic'],ignore_index=True).head(10)"
      ],
      "execution_count": 26,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-8e01df05-4d99-4da7-b64e-a884cc96b11a\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "      <th>PE</th>\n",
              "      <th>PB</th>\n",
              "      <th>Div_yield</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200.0</td>\n",
              "      <td>0.217886</td>\n",
              "      <td>0.163846</td>\n",
              "      <td>0.103222</td>\n",
              "      <td>0.183579</td>\n",
              "      <td>2.461857</td>\n",
              "      <td>2.039779</td>\n",
              "      <td>1.818995</td>\n",
              "      <td>54.403846</td>\n",
              "      <td>8.972003</td>\n",
              "      <td>4.269115</td>\n",
              "      <td>0.437727</td>\n",
              "      <td>0.778495</td>\n",
              "      <td>0.638800</td>\n",
              "      <td>0.101947</td>\n",
              "      <td>0.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>1</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615871</td>\n",
              "      <td>6547900.0</td>\n",
              "      <td>0.093973</td>\n",
              "      <td>0.072040</td>\n",
              "      <td>0.014094</td>\n",
              "      <td>0.108238</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.351354</td>\n",
              "      <td>0.653355</td>\n",
              "      <td>0.869784</td>\n",
              "      <td>6.679531</td>\n",
              "      <td>147.147972</td>\n",
              "      <td>4.224496</td>\n",
              "      <td>0.003946</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AXP</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.579438</td>\n",
              "      <td>10955700.0</td>\n",
              "      <td>0.093973</td>\n",
              "      <td>0.072040</td>\n",
              "      <td>0.014094</td>\n",
              "      <td>0.108238</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.351354</td>\n",
              "      <td>0.653355</td>\n",
              "      <td>0.869784</td>\n",
              "      <td>6.679531</td>\n",
              "      <td>50.256252</td>\n",
              "      <td>1.442815</td>\n",
              "      <td>0.011554</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>3</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>BA</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941101</td>\n",
              "      <td>7010200.0</td>\n",
              "      <td>0.047307</td>\n",
              "      <td>0.032525</td>\n",
              "      <td>0.026400</td>\n",
              "      <td>-2.870334</td>\n",
              "      <td>0.927883</td>\n",
              "      <td>0.368463</td>\n",
              "      <td>0.148507</td>\n",
              "      <td>2.329670</td>\n",
              "      <td>6.815203</td>\n",
              "      <td>2.076967</td>\n",
              "      <td>1.009198</td>\n",
              "      <td>-109.722986</td>\n",
              "      <td>39.012760</td>\n",
              "      <td>-35.751054</td>\n",
              "      <td>0.012374</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>4</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CAT</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475807</td>\n",
              "      <td>7117200.0</td>\n",
              "      <td>0.124545</td>\n",
              "      <td>0.066662</td>\n",
              "      <td>0.040891</td>\n",
              "      <td>0.415878</td>\n",
              "      <td>1.343293</td>\n",
              "      <td>0.890488</td>\n",
              "      <td>0.163158</td>\n",
              "      <td>3.540791</td>\n",
              "      <td>2.460351</td>\n",
              "      <td>8.472455</td>\n",
              "      <td>0.893715</td>\n",
              "      <td>9.089489</td>\n",
              "      <td>-170.925301</td>\n",
              "      <td>3.134587</td>\n",
              "      <td>0.012933</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>5</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CRM</td>\n",
              "      <td>8.025000</td>\n",
              "      <td>8.550000</td>\n",
              "      <td>7.912500</td>\n",
              "      <td>8.505000</td>\n",
              "      <td>4069200.0</td>\n",
              "      <td>0.234698</td>\n",
              "      <td>0.196418</td>\n",
              "      <td>0.097593</td>\n",
              "      <td>0.162793</td>\n",
              "      <td>2.792929</td>\n",
              "      <td>2.498162</td>\n",
              "      <td>2.170759</td>\n",
              "      <td>9.054201</td>\n",
              "      <td>6.844634</td>\n",
              "      <td>16.036800</td>\n",
              "      <td>0.400215</td>\n",
              "      <td>0.667591</td>\n",
              "      <td>13.500000</td>\n",
              "      <td>1.351255</td>\n",
              "      <td>0.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>6</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CSCO</td>\n",
              "      <td>16.410000</td>\n",
              "      <td>17.000000</td>\n",
              "      <td>16.250000</td>\n",
              "      <td>12.349071</td>\n",
              "      <td>40980600.0</td>\n",
              "      <td>0.234698</td>\n",
              "      <td>0.196418</td>\n",
              "      <td>0.097593</td>\n",
              "      <td>0.162793</td>\n",
              "      <td>2.792929</td>\n",
              "      <td>2.498162</td>\n",
              "      <td>2.170759</td>\n",
              "      <td>9.054201</td>\n",
              "      <td>6.844634</td>\n",
              "      <td>16.036800</td>\n",
              "      <td>0.400215</td>\n",
              "      <td>0.667591</td>\n",
              "      <td>19.601699</td>\n",
              "      <td>1.961992</td>\n",
              "      <td>0.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>7</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CVX</td>\n",
              "      <td>74.230003</td>\n",
              "      <td>77.300003</td>\n",
              "      <td>73.580002</td>\n",
              "      <td>45.650551</td>\n",
              "      <td>13695900.0</td>\n",
              "      <td>0.141417</td>\n",
              "      <td>0.097223</td>\n",
              "      <td>0.117691</td>\n",
              "      <td>0.213663</td>\n",
              "      <td>1.368819</td>\n",
              "      <td>0.952878</td>\n",
              "      <td>0.373760</td>\n",
              "      <td>23.920348</td>\n",
              "      <td>13.387209</td>\n",
              "      <td>11.276861</td>\n",
              "      <td>0.449174</td>\n",
              "      <td>0.815455</td>\n",
              "      <td>49.620164</td>\n",
              "      <td>1.048119</td>\n",
              "      <td>0.014239</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>8</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>DIS</td>\n",
              "      <td>22.760000</td>\n",
              "      <td>24.030001</td>\n",
              "      <td>22.500000</td>\n",
              "      <td>20.597496</td>\n",
              "      <td>9796600.0</td>\n",
              "      <td>0.167221</td>\n",
              "      <td>0.102157</td>\n",
              "      <td>0.045834</td>\n",
              "      <td>0.084230</td>\n",
              "      <td>1.175830</td>\n",
              "      <td>0.815629</td>\n",
              "      <td>0.330748</td>\n",
              "      <td>11.310223</td>\n",
              "      <td>5.725855</td>\n",
              "      <td>4.287167</td>\n",
              "      <td>0.455848</td>\n",
              "      <td>0.837721</td>\n",
              "      <td>26.072780</td>\n",
              "      <td>1.126511</td>\n",
              "      <td>0.016992</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>9</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>DOW</td>\n",
              "      <td>52.750000</td>\n",
              "      <td>53.500000</td>\n",
              "      <td>49.500000</td>\n",
              "      <td>42.869854</td>\n",
              "      <td>2350800.0</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>186.390669</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-8e01df05-4d99-4da7-b64e-a884cc96b11a')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-8e01df05-4d99-4da7-b64e-a884cc96b11a button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-8e01df05-4d99-4da7-b64e-a884cc96b11a');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date   tic       open  ...          PE         PB  Div_yield\n",
              "0 2009-01-02  AAPL   3.067143  ...    0.638800   0.101947   0.000000\n",
              "1 2009-01-02  AMGN  58.590000  ...  147.147972   4.224496   0.003946\n",
              "2 2009-01-02   AXP  18.570000  ...   50.256252   1.442815   0.011554\n",
              "3 2009-01-02    BA  42.799999  ...   39.012760 -35.751054   0.012374\n",
              "4 2009-01-02   CAT  44.910000  ... -170.925301   3.134587   0.012933\n",
              "5 2009-01-02   CRM   8.025000  ...   13.500000   1.351255   0.000000\n",
              "6 2009-01-02  CSCO  16.410000  ...   19.601699   1.961992   0.000000\n",
              "7 2009-01-02   CVX  74.230003  ...   49.620164   1.048119   0.014239\n",
              "8 2009-01-02   DIS  22.760000  ...   26.072780   1.126511   0.016992\n",
              "9 2009-01-02   DOW  52.750000  ...  186.390669   0.000000   0.000000\n",
              "\n",
              "[10 rows x 22 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 26
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-QsYaY0Dh1iw"
      },
      "source": [
        "<a id='4'></a>\n",
        "# Part 5. Design Environment\n",
        "Considering the stochastic and interactive nature of the automated stock trading tasks, a financial task is modeled as a **Markov Decision Process (MDP)** problem. The training process involves observing stock price change, taking an action and reward's calculation to have the agent adjusting its strategy accordingly. By interacting with the environment, the trading agent will derive a trading strategy with the maximized rewards as time proceeds.\n",
        "\n",
        "Our trading environments, based on OpenAI Gym framework, simulate live stock markets with real market data according to the principle of time-driven simulation.\n",
        "\n",
        "The action space describes the allowed actions that the agent interacts with the environment. Normally, action a includes three actions: {-1, 0, 1}, where -1, 0, 1 represent selling, holding, and buying one share. Also, an action can be carried upon multiple shares. We use an action space {-k,…,-1, 0, 1, …, k}, where k denotes the number of shares to buy and -k denotes the number of shares to sell. For example, \"Buy 10 shares of AAPL\" or \"Sell 10 shares of AAPL\" are 10 or -10, respectively. The continuous action space needs to be normalized to [-1, 1], since the policy is defined on a Gaussian distribution, which needs to be normalized and symmetric."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "5TOhcryx44bb"
      },
      "source": [
        "## 5-1 Split data into training and trade dataset\n",
        "- Training data split: 2009-01-01 to 2018-12-31\n",
        "- Trade data split: 2019-01-01 to 2020-09-30"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "W0qaVGjLtgbI",
        "outputId": "9aa29c96-0c58-41cc-c022-3d9a60faf047"
      },
      "source": [
        "train = data_split(processed_full, '2009-01-01','2019-01-01')\n",
        "trade = data_split(processed_full, '2019-01-01','2021-01-01')\n",
        "# Check the length of the two datasets\n",
        "print(len(train))\n",
        "print(len(trade))"
      ],
      "execution_count": 27,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "109530\n",
            "21930\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "id": "p52zNCOhTtLR",
        "outputId": "f4a5a898-c30c-4f01-a97b-35a54040d093"
      },
      "source": [
        "train.head()"
      ],
      "execution_count": 28,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-ddd1447b-e628-4db5-ad53-15f87c7c9651\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "      <th>PE</th>\n",
              "      <th>PB</th>\n",
              "      <th>Div_yield</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>3.067143</td>\n",
              "      <td>3.251429</td>\n",
              "      <td>3.041429</td>\n",
              "      <td>2.778782</td>\n",
              "      <td>746015200.0</td>\n",
              "      <td>0.217886</td>\n",
              "      <td>0.163846</td>\n",
              "      <td>0.103222</td>\n",
              "      <td>0.183579</td>\n",
              "      <td>2.461857</td>\n",
              "      <td>2.039779</td>\n",
              "      <td>1.818995</td>\n",
              "      <td>54.403846</td>\n",
              "      <td>8.972003</td>\n",
              "      <td>4.269115</td>\n",
              "      <td>0.437727</td>\n",
              "      <td>0.778495</td>\n",
              "      <td>0.638800</td>\n",
              "      <td>0.101947</td>\n",
              "      <td>0.000000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>58.590000</td>\n",
              "      <td>59.080002</td>\n",
              "      <td>57.750000</td>\n",
              "      <td>45.615871</td>\n",
              "      <td>6547900.0</td>\n",
              "      <td>0.093973</td>\n",
              "      <td>0.072040</td>\n",
              "      <td>0.014094</td>\n",
              "      <td>0.108238</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.351354</td>\n",
              "      <td>0.653355</td>\n",
              "      <td>0.869784</td>\n",
              "      <td>6.679531</td>\n",
              "      <td>147.147972</td>\n",
              "      <td>4.224496</td>\n",
              "      <td>0.003946</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>AXP</td>\n",
              "      <td>18.570000</td>\n",
              "      <td>19.520000</td>\n",
              "      <td>18.400000</td>\n",
              "      <td>15.579438</td>\n",
              "      <td>10955700.0</td>\n",
              "      <td>0.093973</td>\n",
              "      <td>0.072040</td>\n",
              "      <td>0.014094</td>\n",
              "      <td>0.108238</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.351354</td>\n",
              "      <td>0.653355</td>\n",
              "      <td>0.869784</td>\n",
              "      <td>6.679531</td>\n",
              "      <td>50.256252</td>\n",
              "      <td>1.442815</td>\n",
              "      <td>0.011554</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>BA</td>\n",
              "      <td>42.799999</td>\n",
              "      <td>45.560001</td>\n",
              "      <td>42.779999</td>\n",
              "      <td>33.941101</td>\n",
              "      <td>7010200.0</td>\n",
              "      <td>0.047307</td>\n",
              "      <td>0.032525</td>\n",
              "      <td>0.026400</td>\n",
              "      <td>-2.870334</td>\n",
              "      <td>0.927883</td>\n",
              "      <td>0.368463</td>\n",
              "      <td>0.148507</td>\n",
              "      <td>2.329670</td>\n",
              "      <td>6.815203</td>\n",
              "      <td>2.076967</td>\n",
              "      <td>1.009198</td>\n",
              "      <td>-109.722986</td>\n",
              "      <td>39.012760</td>\n",
              "      <td>-35.751054</td>\n",
              "      <td>0.012374</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2009-01-02</td>\n",
              "      <td>CAT</td>\n",
              "      <td>44.910000</td>\n",
              "      <td>46.980000</td>\n",
              "      <td>44.709999</td>\n",
              "      <td>32.475807</td>\n",
              "      <td>7117200.0</td>\n",
              "      <td>0.124545</td>\n",
              "      <td>0.066662</td>\n",
              "      <td>0.040891</td>\n",
              "      <td>0.415878</td>\n",
              "      <td>1.343293</td>\n",
              "      <td>0.890488</td>\n",
              "      <td>0.163158</td>\n",
              "      <td>3.540791</td>\n",
              "      <td>2.460351</td>\n",
              "      <td>8.472455</td>\n",
              "      <td>0.893715</td>\n",
              "      <td>9.089489</td>\n",
              "      <td>-170.925301</td>\n",
              "      <td>3.134587</td>\n",
              "      <td>0.012933</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-ddd1447b-e628-4db5-ad53-15f87c7c9651')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-ddd1447b-e628-4db5-ad53-15f87c7c9651 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-ddd1447b-e628-4db5-ad53-15f87c7c9651');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date   tic       open  ...          PE         PB  Div_yield\n",
              "0 2009-01-02  AAPL   3.067143  ...    0.638800   0.101947   0.000000\n",
              "0 2009-01-02  AMGN  58.590000  ...  147.147972   4.224496   0.003946\n",
              "0 2009-01-02   AXP  18.570000  ...   50.256252   1.442815   0.011554\n",
              "0 2009-01-02    BA  42.799999  ...   39.012760 -35.751054   0.012374\n",
              "0 2009-01-02   CAT  44.910000  ... -170.925301   3.134587   0.012933\n",
              "\n",
              "[5 rows x 22 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 28
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 357
        },
        "id": "k9zU9YaTTvFq",
        "outputId": "b81d06aa-bc50-4ace-ca77-bd794ac547af"
      },
      "source": [
        "trade.head()"
      ],
      "execution_count": 29,
      "outputs": [
        {
          "output_type": "execute_result",
          "data": {
            "text/html": [
              "\n",
              "  <div id=\"df-1ba23087-dfae-4e2e-a677-e77cecef5ed5\">\n",
              "    <div class=\"colab-df-container\">\n",
              "      <div>\n",
              "<style scoped>\n",
              "    .dataframe tbody tr th:only-of-type {\n",
              "        vertical-align: middle;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: right;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>date</th>\n",
              "      <th>tic</th>\n",
              "      <th>open</th>\n",
              "      <th>high</th>\n",
              "      <th>low</th>\n",
              "      <th>close</th>\n",
              "      <th>volume</th>\n",
              "      <th>OPM</th>\n",
              "      <th>NPM</th>\n",
              "      <th>ROA</th>\n",
              "      <th>ROE</th>\n",
              "      <th>cur_ratio</th>\n",
              "      <th>quick_ratio</th>\n",
              "      <th>cash_ratio</th>\n",
              "      <th>inv_turnover</th>\n",
              "      <th>acc_rec_turnover</th>\n",
              "      <th>acc_pay_turnover</th>\n",
              "      <th>debt_ratio</th>\n",
              "      <th>debt_to_equity</th>\n",
              "      <th>PE</th>\n",
              "      <th>PB</th>\n",
              "      <th>Div_yield</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2019-01-01</td>\n",
              "      <td>AAPL</td>\n",
              "      <td>38.722500</td>\n",
              "      <td>39.712502</td>\n",
              "      <td>38.557499</td>\n",
              "      <td>38.326298</td>\n",
              "      <td>148158800.0</td>\n",
              "      <td>0.258891</td>\n",
              "      <td>0.227773</td>\n",
              "      <td>0.133360</td>\n",
              "      <td>0.430843</td>\n",
              "      <td>1.315382</td>\n",
              "      <td>1.134347</td>\n",
              "      <td>0.854114</td>\n",
              "      <td>23.571867</td>\n",
              "      <td>7.620024</td>\n",
              "      <td>3.781658</td>\n",
              "      <td>0.690466</td>\n",
              "      <td>2.230663</td>\n",
              "      <td>5.720343</td>\n",
              "      <td>1.668053</td>\n",
              "      <td>0.019047</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2019-01-01</td>\n",
              "      <td>AMGN</td>\n",
              "      <td>192.520004</td>\n",
              "      <td>193.199997</td>\n",
              "      <td>188.949997</td>\n",
              "      <td>175.788910</td>\n",
              "      <td>3009100.0</td>\n",
              "      <td>0.093973</td>\n",
              "      <td>0.072040</td>\n",
              "      <td>0.014094</td>\n",
              "      <td>0.108238</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.351354</td>\n",
              "      <td>0.653355</td>\n",
              "      <td>0.869784</td>\n",
              "      <td>6.679531</td>\n",
              "      <td>567.061000</td>\n",
              "      <td>16.279848</td>\n",
              "      <td>0.001024</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2019-01-01</td>\n",
              "      <td>AXP</td>\n",
              "      <td>93.910004</td>\n",
              "      <td>96.269997</td>\n",
              "      <td>93.769997</td>\n",
              "      <td>91.346497</td>\n",
              "      <td>4175400.0</td>\n",
              "      <td>0.203479</td>\n",
              "      <td>0.160494</td>\n",
              "      <td>0.026811</td>\n",
              "      <td>0.237960</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.000000</td>\n",
              "      <td>0.231669</td>\n",
              "      <td>0.279424</td>\n",
              "      <td>0.887329</td>\n",
              "      <td>7.875371</td>\n",
              "      <td>50.467678</td>\n",
              "      <td>3.441220</td>\n",
              "      <td>0.004269</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2019-01-01</td>\n",
              "      <td>BA</td>\n",
              "      <td>316.190002</td>\n",
              "      <td>323.950012</td>\n",
              "      <td>313.709991</td>\n",
              "      <td>314.645172</td>\n",
              "      <td>3292200.0</td>\n",
              "      <td>0.116496</td>\n",
              "      <td>0.102682</td>\n",
              "      <td>0.066409</td>\n",
              "      <td>34.409483</td>\n",
              "      <td>1.070490</td>\n",
              "      <td>0.262465</td>\n",
              "      <td>0.092436</td>\n",
              "      <td>0.933164</td>\n",
              "      <td>5.468453</td>\n",
              "      <td>4.151637</td>\n",
              "      <td>0.998070</td>\n",
              "      <td>517.142241</td>\n",
              "      <td>83.019834</td>\n",
              "      <td>1418.196409</td>\n",
              "      <td>0.006531</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>0</th>\n",
              "      <td>2019-01-01</td>\n",
              "      <td>CAT</td>\n",
              "      <td>124.029999</td>\n",
              "      <td>127.879997</td>\n",
              "      <td>123.000000</td>\n",
              "      <td>116.861320</td>\n",
              "      <td>4783200.0</td>\n",
              "      <td>0.186871</td>\n",
              "      <td>0.107064</td>\n",
              "      <td>0.056932</td>\n",
              "      <td>0.289572</td>\n",
              "      <td>1.428582</td>\n",
              "      <td>0.919490</td>\n",
              "      <td>0.266175</td>\n",
              "      <td>2.135008</td>\n",
              "      <td>2.339630</td>\n",
              "      <td>3.660183</td>\n",
              "      <td>0.803394</td>\n",
              "      <td>4.086316</td>\n",
              "      <td>35.520158</td>\n",
              "      <td>4.327904</td>\n",
              "      <td>0.007359</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>\n",
              "      <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-1ba23087-dfae-4e2e-a677-e77cecef5ed5')\"\n",
              "              title=\"Convert this dataframe to an interactive table.\"\n",
              "              style=\"display:none;\">\n",
              "        \n",
              "  <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n",
              "       width=\"24px\">\n",
              "    <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n",
              "    <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n",
              "  </svg>\n",
              "      </button>\n",
              "      \n",
              "  <style>\n",
              "    .colab-df-container {\n",
              "      display:flex;\n",
              "      flex-wrap:wrap;\n",
              "      gap: 12px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert {\n",
              "      background-color: #E8F0FE;\n",
              "      border: none;\n",
              "      border-radius: 50%;\n",
              "      cursor: pointer;\n",
              "      display: none;\n",
              "      fill: #1967D2;\n",
              "      height: 32px;\n",
              "      padding: 0 0 0 0;\n",
              "      width: 32px;\n",
              "    }\n",
              "\n",
              "    .colab-df-convert:hover {\n",
              "      background-color: #E2EBFA;\n",
              "      box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
              "      fill: #174EA6;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert {\n",
              "      background-color: #3B4455;\n",
              "      fill: #D2E3FC;\n",
              "    }\n",
              "\n",
              "    [theme=dark] .colab-df-convert:hover {\n",
              "      background-color: #434B5C;\n",
              "      box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
              "      filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
              "      fill: #FFFFFF;\n",
              "    }\n",
              "  </style>\n",
              "\n",
              "      <script>\n",
              "        const buttonEl =\n",
              "          document.querySelector('#df-1ba23087-dfae-4e2e-a677-e77cecef5ed5 button.colab-df-convert');\n",
              "        buttonEl.style.display =\n",
              "          google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
              "\n",
              "        async function convertToInteractive(key) {\n",
              "          const element = document.querySelector('#df-1ba23087-dfae-4e2e-a677-e77cecef5ed5');\n",
              "          const dataTable =\n",
              "            await google.colab.kernel.invokeFunction('convertToInteractive',\n",
              "                                                     [key], {});\n",
              "          if (!dataTable) return;\n",
              "\n",
              "          const docLinkHtml = 'Like what you see? Visit the ' +\n",
              "            '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
              "            + ' to learn more about interactive tables.';\n",
              "          element.innerHTML = '';\n",
              "          dataTable['output_type'] = 'display_data';\n",
              "          await google.colab.output.renderOutput(dataTable, element);\n",
              "          const docLink = document.createElement('div');\n",
              "          docLink.innerHTML = docLinkHtml;\n",
              "          element.appendChild(docLink);\n",
              "        }\n",
              "      </script>\n",
              "    </div>\n",
              "  </div>\n",
              "  "
            ],
            "text/plain": [
              "        date   tic        open  ...          PE           PB  Div_yield\n",
              "0 2019-01-01  AAPL   38.722500  ...    5.720343     1.668053   0.019047\n",
              "0 2019-01-01  AMGN  192.520004  ...  567.061000    16.279848   0.001024\n",
              "0 2019-01-01   AXP   93.910004  ...   50.467678     3.441220   0.004269\n",
              "0 2019-01-01    BA  316.190002  ...   83.019834  1418.196409   0.006531\n",
              "0 2019-01-01   CAT  124.029999  ...   35.520158     4.327904   0.007359\n",
              "\n",
              "[5 rows x 22 columns]"
            ]
          },
          "metadata": {},
          "execution_count": 29
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "qqGG78pLyCX7"
      },
      "source": [
        "## 5-2 Set up the training environment"
      ]
    },
    {
      "cell_type": "code",
      "source": [
        "import gym\n",
        "import matplotlib\n",
        "import matplotlib.pyplot as plt\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "from gym import spaces\n",
        "from gym.utils import seeding\n",
        "from stable_baselines3.common.vec_env import DummyVecEnv\n",
        "\n",
        "matplotlib.use(\"Agg\")\n",
        "\n",
        "# from stable_baselines3.common import logger\n",
        "\n",
        "\n",
        "class StockTradingEnv(gym.Env):\n",
        "    \"\"\"A stock trading environment for OpenAI gym\"\"\"\n",
        "\n",
        "    metadata = {\"render.modes\": [\"human\"]}\n",
        "\n",
        "    def __init__(\n",
        "        self,\n",
        "        df,\n",
        "        stock_dim,\n",
        "        hmax,\n",
        "        initial_amount,\n",
        "        buy_cost_pct,\n",
        "        sell_cost_pct,\n",
        "        reward_scaling,\n",
        "        state_space,\n",
        "        action_space,\n",
        "        tech_indicator_list,\n",
        "        turbulence_threshold=None,\n",
        "        risk_indicator_col=\"turbulence\",\n",
        "        make_plots=False,\n",
        "        print_verbosity=10,\n",
        "        day=0,\n",
        "        initial=True,\n",
        "        previous_state=[],\n",
        "        model_name=\"\",\n",
        "        mode=\"\",\n",
        "        iteration=\"\",\n",
        "    ):\n",
        "        self.day = day\n",
        "        self.df = df\n",
        "        self.stock_dim = stock_dim\n",
        "        self.hmax = hmax\n",
        "        self.initial_amount = initial_amount\n",
        "        self.buy_cost_pct = buy_cost_pct\n",
        "        self.sell_cost_pct = sell_cost_pct\n",
        "        self.reward_scaling = reward_scaling\n",
        "        self.state_space = state_space\n",
        "        self.action_space = action_space\n",
        "        self.tech_indicator_list = tech_indicator_list\n",
        "        self.action_space = spaces.Box(low=-1, high=1, shape=(self.action_space,))\n",
        "        self.observation_space = spaces.Box(\n",
        "            low=-np.inf, high=np.inf, shape=(self.state_space,)\n",
        "        )\n",
        "        self.data = self.df.loc[self.day, :]\n",
        "        self.terminal = False\n",
        "        self.make_plots = make_plots\n",
        "        self.print_verbosity = print_verbosity\n",
        "        self.turbulence_threshold = turbulence_threshold\n",
        "        self.risk_indicator_col = risk_indicator_col\n",
        "        self.initial = initial\n",
        "        self.previous_state = previous_state\n",
        "        self.model_name = model_name\n",
        "        self.mode = mode\n",
        "        self.iteration = iteration\n",
        "        # initalize state\n",
        "        self.state = self._initiate_state()\n",
        "\n",
        "        # initialize reward\n",
        "        self.reward = 0\n",
        "        self.turbulence = 0\n",
        "        self.cost = 0\n",
        "        self.trades = 0\n",
        "        self.episode = 0\n",
        "        # memorize all the total balance change\n",
        "        self.asset_memory = [self.initial_amount]\n",
        "        self.rewards_memory = []\n",
        "        self.actions_memory = []\n",
        "        self.date_memory = [self._get_date()]\n",
        "        # self.reset()\n",
        "        self._seed()\n",
        "\n",
        "    def _sell_stock(self, index, action):\n",
        "        def _do_sell_normal():\n",
        "            if self.state[index + 1] > 0:\n",
        "                # Sell only if the price is > 0 (no missing data in this particular date)\n",
        "                # perform sell action based on the sign of the action\n",
        "                if self.state[index + self.stock_dim + 1] > 0:\n",
        "                    # Sell only if current asset is > 0\n",
        "                    sell_num_shares = min(\n",
        "                        abs(action), self.state[index + self.stock_dim + 1]\n",
        "                    )\n",
        "                    sell_amount = (\n",
        "                        self.state[index + 1]\n",
        "                        * sell_num_shares\n",
        "                        * (1 - self.sell_cost_pct)\n",
        "                    )\n",
        "                    # update balance\n",
        "                    self.state[0] += sell_amount\n",
        "\n",
        "                    self.state[index + self.stock_dim + 1] -= sell_num_shares\n",
        "                    self.cost += (\n",
        "                        self.state[index + 1] * sell_num_shares * self.sell_cost_pct\n",
        "                    )\n",
        "                    self.trades += 1\n",
        "                else:\n",
        "                    sell_num_shares = 0\n",
        "            else:\n",
        "                sell_num_shares = 0\n",
        "\n",
        "            return sell_num_shares\n",
        "\n",
        "        # perform sell action based on the sign of the action\n",
        "        if self.turbulence_threshold is not None:\n",
        "            if self.turbulence >= self.turbulence_threshold:\n",
        "                if self.state[index + 1] > 0:\n",
        "                    # Sell only if the price is > 0 (no missing data in this particular date)\n",
        "                    # if turbulence goes over threshold, just clear out all positions\n",
        "                    if self.state[index + self.stock_dim + 1] > 0:\n",
        "                        # Sell only if current asset is > 0\n",
        "                        sell_num_shares = self.state[index + self.stock_dim + 1]\n",
        "                        sell_amount = (\n",
        "                            self.state[index + 1]\n",
        "                            * sell_num_shares\n",
        "                            * (1 - self.sell_cost_pct)\n",
        "                        )\n",
        "                        # update balance\n",
        "                        self.state[0] += sell_amount\n",
        "                        self.state[index + self.stock_dim + 1] = 0\n",
        "                        self.cost += (\n",
        "                            self.state[index + 1] * sell_num_shares * self.sell_cost_pct\n",
        "                        )\n",
        "                        self.trades += 1\n",
        "                    else:\n",
        "                        sell_num_shares = 0\n",
        "                else:\n",
        "                    sell_num_shares = 0\n",
        "            else:\n",
        "                sell_num_shares = _do_sell_normal()\n",
        "        else:\n",
        "            sell_num_shares = _do_sell_normal()\n",
        "\n",
        "        return sell_num_shares\n",
        "\n",
        "    def _buy_stock(self, index, action):\n",
        "        def _do_buy():\n",
        "            if self.state[index + 1] > 0:\n",
        "                # Buy only if the price is > 0 (no missing data in this particular date)\n",
        "                available_amount = self.state[0] // self.state[index + 1]\n",
        "                # print('available_amount:{}'.format(available_amount))\n",
        "\n",
        "                # update balance\n",
        "                buy_num_shares = min(available_amount, action)\n",
        "                buy_amount = (\n",
        "                    self.state[index + 1] * buy_num_shares * (1 + self.buy_cost_pct)\n",
        "                )\n",
        "                self.state[0] -= buy_amount\n",
        "\n",
        "                self.state[index + self.stock_dim + 1] += buy_num_shares\n",
        "\n",
        "                self.cost += self.state[index + 1] * buy_num_shares * self.buy_cost_pct\n",
        "                self.trades += 1\n",
        "            else:\n",
        "                buy_num_shares = 0\n",
        "\n",
        "            return buy_num_shares\n",
        "\n",
        "        # perform buy action based on the sign of the action\n",
        "        if self.turbulence_threshold is None:\n",
        "            buy_num_shares = _do_buy()\n",
        "        else:\n",
        "            if self.turbulence < self.turbulence_threshold:\n",
        "                buy_num_shares = _do_buy()\n",
        "            else:\n",
        "                buy_num_shares = 0\n",
        "                pass\n",
        "\n",
        "        return buy_num_shares\n",
        "\n",
        "    def _make_plot(self):\n",
        "        plt.plot(self.asset_memory, \"r\")\n",
        "        plt.savefig(\"results/account_value_trade_{}.png\".format(self.episode))\n",
        "        plt.close()\n",
        "\n",
        "    def step(self, actions):\n",
        "        self.terminal = self.day >= len(self.df.index.unique()) - 1\n",
        "        if self.terminal:\n",
        "            # print(f\"Episode: {self.episode}\")\n",
        "            if self.make_plots:\n",
        "                self._make_plot()\n",
        "            end_total_asset = self.state[0] + sum(\n",
        "                np.array(self.state[1 : (self.stock_dim + 1)])\n",
        "                * np.array(self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)])\n",
        "            )\n",
        "            df_total_value = pd.DataFrame(self.asset_memory)\n",
        "            tot_reward = (\n",
        "                self.state[0]\n",
        "                + sum(\n",
        "                    np.array(self.state[1 : (self.stock_dim + 1)])\n",
        "                    * np.array(\n",
        "                        self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)]\n",
        "                    )\n",
        "                )\n",
        "                - self.initial_amount\n",
        "            )\n",
        "            df_total_value.columns = [\"account_value\"]\n",
        "            df_total_value[\"date\"] = self.date_memory\n",
        "            df_total_value[\"daily_return\"] = df_total_value[\"account_value\"].pct_change(\n",
        "                1\n",
        "            )\n",
        "            if df_total_value[\"daily_return\"].std() != 0:\n",
        "                sharpe = (\n",
        "                    (252 ** 0.5)\n",
        "                    * df_total_value[\"daily_return\"].mean()\n",
        "                    / df_total_value[\"daily_return\"].std()\n",
        "                )\n",
        "            df_rewards = pd.DataFrame(self.rewards_memory)\n",
        "            df_rewards.columns = [\"account_rewards\"]\n",
        "            df_rewards[\"date\"] = self.date_memory[:-1]\n",
        "            if self.episode % self.print_verbosity == 0:\n",
        "                print(f\"day: {self.day}, episode: {self.episode}\")\n",
        "                print(f\"begin_total_asset: {self.asset_memory[0]:0.2f}\")\n",
        "                print(f\"end_total_asset: {end_total_asset:0.2f}\")\n",
        "                print(f\"total_reward: {tot_reward:0.2f}\")\n",
        "                print(f\"total_cost: {self.cost:0.2f}\")\n",
        "                print(f\"total_trades: {self.trades}\")\n",
        "                if df_total_value[\"daily_return\"].std() != 0:\n",
        "                    print(f\"Sharpe: {sharpe:0.3f}\")\n",
        "                print(\"=================================\")\n",
        "\n",
        "            if (self.model_name != \"\") and (self.mode != \"\"):\n",
        "                df_actions = self.save_action_memory()\n",
        "                df_actions.to_csv(\n",
        "                    \"results/actions_{}_{}_{}.csv\".format(\n",
        "                        self.mode, self.model_name, self.iteration\n",
        "                    )\n",
        "                )\n",
        "                df_total_value.to_csv(\n",
        "                    \"results/account_value_{}_{}_{}.csv\".format(\n",
        "                        self.mode, self.model_name, self.iteration\n",
        "                    ),\n",
        "                    index=False,\n",
        "                )\n",
        "                df_rewards.to_csv(\n",
        "                    \"results/account_rewards_{}_{}_{}.csv\".format(\n",
        "                        self.mode, self.model_name, self.iteration\n",
        "                    ),\n",
        "                    index=False,\n",
        "                )\n",
        "                plt.plot(self.asset_memory, \"r\")\n",
        "                plt.savefig(\n",
        "                    \"results/account_value_{}_{}_{}.png\".format(\n",
        "                        self.mode, self.model_name, self.iteration\n",
        "                    ),\n",
        "                    index=False,\n",
        "                )\n",
        "                plt.close()\n",
        "\n",
        "            # Add outputs to logger interface\n",
        "            # logger.record(\"environment/portfolio_value\", end_total_asset)\n",
        "            # logger.record(\"environment/total_reward\", tot_reward)\n",
        "            # logger.record(\"environment/total_reward_pct\", (tot_reward / (end_total_asset - tot_reward)) * 100)\n",
        "            # logger.record(\"environment/total_cost\", self.cost)\n",
        "            # logger.record(\"environment/total_trades\", self.trades)\n",
        "\n",
        "            return self.state, self.reward, self.terminal, {}\n",
        "\n",
        "        else:\n",
        "\n",
        "            actions = actions * self.hmax  # actions initially is scaled between 0 to 1\n",
        "            actions = actions.astype(\n",
        "                int\n",
        "            )  # convert into integer because we can't by fraction of shares\n",
        "            if self.turbulence_threshold is not None:\n",
        "                if self.turbulence >= self.turbulence_threshold:\n",
        "                    actions = np.array([-self.hmax] * self.stock_dim)\n",
        "            begin_total_asset = self.state[0] + sum(\n",
        "                np.array(self.state[1 : (self.stock_dim + 1)])\n",
        "                * np.array(self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)])\n",
        "            )\n",
        "            # print(\"begin_total_asset:{}\".format(begin_total_asset))\n",
        "\n",
        "            argsort_actions = np.argsort(actions)\n",
        "\n",
        "            sell_index = argsort_actions[: np.where(actions < 0)[0].shape[0]]\n",
        "            buy_index = argsort_actions[::-1][: np.where(actions > 0)[0].shape[0]]\n",
        "\n",
        "            for index in sell_index:\n",
        "                # print(f\"Num shares before: {self.state[index+self.stock_dim+1]}\")\n",
        "                # print(f'take sell action before : {actions[index]}')\n",
        "                actions[index] = self._sell_stock(index, actions[index]) * (-1)\n",
        "                # print(f'take sell action after : {actions[index]}')\n",
        "                # print(f\"Num shares after: {self.state[index+self.stock_dim+1]}\")\n",
        "\n",
        "            for index in buy_index:\n",
        "                # print('take buy action: {}'.format(actions[index]))\n",
        "                actions[index] = self._buy_stock(index, actions[index])\n",
        "\n",
        "            self.actions_memory.append(actions)\n",
        "\n",
        "            # state: s -> s+1\n",
        "            self.day += 1\n",
        "            self.data = self.df.loc[self.day, :]\n",
        "            if self.turbulence_threshold is not None:\n",
        "                if len(self.df.tic.unique()) == 1:\n",
        "                    self.turbulence = self.data[self.risk_indicator_col]\n",
        "                elif len(self.df.tic.unique()) > 1:\n",
        "                    self.turbulence = self.data[self.risk_indicator_col].values[0]\n",
        "            self.state = self._update_state()\n",
        "\n",
        "            end_total_asset = self.state[0] + sum(\n",
        "                np.array(self.state[1 : (self.stock_dim + 1)])\n",
        "                * np.array(self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)])\n",
        "            )\n",
        "            self.asset_memory.append(end_total_asset)\n",
        "            self.date_memory.append(self._get_date())\n",
        "            self.reward = end_total_asset - begin_total_asset\n",
        "            self.rewards_memory.append(self.reward)\n",
        "            self.reward = self.reward * self.reward_scaling\n",
        "\n",
        "        return self.state, self.reward, self.terminal, {}\n",
        "\n",
        "    def reset(self):\n",
        "        # initiate state\n",
        "        self.state = self._initiate_state()\n",
        "\n",
        "        if self.initial:\n",
        "            self.asset_memory = [self.initial_amount]\n",
        "        else:\n",
        "            previous_total_asset = self.previous_state[0] + sum(\n",
        "                np.array(self.state[1 : (self.stock_dim + 1)])\n",
        "                * np.array(\n",
        "                    self.previous_state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)]\n",
        "                )\n",
        "            )\n",
        "            self.asset_memory = [previous_total_asset]\n",
        "\n",
        "        self.day = 0\n",
        "        self.data = self.df.loc[self.day, :]\n",
        "        self.turbulence = 0\n",
        "        self.cost = 0\n",
        "        self.trades = 0\n",
        "        self.terminal = False\n",
        "        # self.iteration=self.iteration\n",
        "        self.rewards_memory = []\n",
        "        self.actions_memory = []\n",
        "        self.date_memory = [self._get_date()]\n",
        "\n",
        "        self.episode += 1\n",
        "\n",
        "        return self.state\n",
        "\n",
        "    def render(self, mode=\"human\", close=False):\n",
        "        return self.state\n",
        "\n",
        "    def _initiate_state(self):\n",
        "        if self.initial:\n",
        "            # For Initial State\n",
        "            if len(self.df.tic.unique()) > 1:\n",
        "                # for multiple stock\n",
        "                state = (\n",
        "                    [self.initial_amount]\n",
        "                    + self.data.close.values.tolist()\n",
        "                    + [0] * self.stock_dim\n",
        "                    + sum(\n",
        "                        [\n",
        "                            self.data[tech].values.tolist()\n",
        "                            for tech in self.tech_indicator_list\n",
        "                        ],\n",
        "                        [],\n",
        "                    )\n",
        "                )\n",
        "            else:\n",
        "                # for single stock\n",
        "                state = (\n",
        "                    [self.initial_amount]\n",
        "                    + [self.data.close]\n",
        "                    + [0] * self.stock_dim\n",
        "                    + sum([[self.data[tech]] for tech in self.tech_indicator_list], [])\n",
        "                )\n",
        "        else:\n",
        "            # Using Previous State\n",
        "            if len(self.df.tic.unique()) > 1:\n",
        "                # for multiple stock\n",
        "                state = (\n",
        "                    [self.previous_state[0]]\n",
        "                    + self.data.close.values.tolist()\n",
        "                    + self.previous_state[\n",
        "                        (self.stock_dim + 1) : (self.stock_dim * 2 + 1)\n",
        "                    ]\n",
        "                    + sum(\n",
        "                        [\n",
        "                            self.data[tech].values.tolist()\n",
        "                            for tech in self.tech_indicator_list\n",
        "                        ],\n",
        "                        [],\n",
        "                    )\n",
        "                )\n",
        "            else:\n",
        "                # for single stock\n",
        "                state = (\n",
        "                    [self.previous_state[0]]\n",
        "                    + [self.data.close]\n",
        "                    + self.previous_state[\n",
        "                        (self.stock_dim + 1) : (self.stock_dim * 2 + 1)\n",
        "                    ]\n",
        "                    + sum([[self.data[tech]] for tech in self.tech_indicator_list], [])\n",
        "                )\n",
        "        return state\n",
        "\n",
        "    def _update_state(self):\n",
        "        if len(self.df.tic.unique()) > 1:\n",
        "            # for multiple stock\n",
        "            state = (\n",
        "                [self.state[0]]\n",
        "                + self.data.close.values.tolist()\n",
        "                + list(self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)])\n",
        "                + sum(\n",
        "                    [\n",
        "                        self.data[tech].values.tolist()\n",
        "                        for tech in self.tech_indicator_list\n",
        "                    ],\n",
        "                    [],\n",
        "                )\n",
        "            )\n",
        "\n",
        "        else:\n",
        "            # for single stock\n",
        "            state = (\n",
        "                [self.state[0]]\n",
        "                + [self.data.close]\n",
        "                + list(self.state[(self.stock_dim + 1) : (self.stock_dim * 2 + 1)])\n",
        "                + sum([[self.data[tech]] for tech in self.tech_indicator_list], [])\n",
        "            )\n",
        "        return state\n",
        "\n",
        "    def _get_date(self):\n",
        "        if len(self.df.tic.unique()) > 1:\n",
        "            date = self.data.date.unique()[0]\n",
        "        else:\n",
        "            date = self.data.date\n",
        "        return date\n",
        "\n",
        "    def save_asset_memory(self):\n",
        "        date_list = self.date_memory\n",
        "        asset_list = self.asset_memory\n",
        "        # print(len(date_list))\n",
        "        # print(len(asset_list))\n",
        "        df_account_value = pd.DataFrame(\n",
        "            {\"date\": date_list, \"account_value\": asset_list}\n",
        "        )\n",
        "        return df_account_value\n",
        "\n",
        "    def save_action_memory(self):\n",
        "        if len(self.df.tic.unique()) > 1:\n",
        "            # date and close price length must match actions length\n",
        "            date_list = self.date_memory[:-1]\n",
        "            df_date = pd.DataFrame(date_list)\n",
        "            df_date.columns = [\"date\"]\n",
        "\n",
        "            action_list = self.actions_memory\n",
        "            df_actions = pd.DataFrame(action_list)\n",
        "            df_actions.columns = self.data.tic.values\n",
        "            df_actions.index = df_date.date\n",
        "            # df_actions = pd.DataFrame({'date':date_list,'actions':action_list})\n",
        "        else:\n",
        "            date_list = self.date_memory[:-1]\n",
        "            action_list = self.actions_memory\n",
        "            df_actions = pd.DataFrame({\"date\": date_list, \"actions\": action_list})\n",
        "        return df_actions\n",
        "\n",
        "    def _seed(self, seed=None):\n",
        "        self.np_random, seed = seeding.np_random(seed)\n",
        "        return [seed]\n",
        "\n",
        "    def get_sb_env(self):\n",
        "        e = DummyVecEnv([lambda: self])\n",
        "        obs = e.reset()\n",
        "        return e, obs"
      ],
      "metadata": {
        "id": "LPD0wZLO-Pse"
      },
      "execution_count": 30,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Q2zqII8rMIqn",
        "outputId": "2dd2d94a-4c01-4f8e-f7f7-a420f4023095"
      },
      "source": [
        "ratio_list = ['OPM', 'NPM','ROA', 'ROE', 'cur_ratio', 'quick_ratio', 'cash_ratio', 'inv_turnover','acc_rec_turnover', 'acc_pay_turnover', 'debt_ratio', 'debt_to_equity',\n",
        "       'PE', 'PB', 'Div_yield']\n",
        "\n",
        "stock_dimension = len(train.tic.unique())\n",
        "state_space = 1 + 2*stock_dimension + len(ratio_list)*stock_dimension\n",
        "print(f\"Stock Dimension: {stock_dimension}, State Space: {state_space}\")"
      ],
      "execution_count": 31,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Stock Dimension: 30, State Space: 511\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "AWyp84Ltto19"
      },
      "source": [
        "# Parameters for the environment\n",
        "env_kwargs = {\n",
        "    \"hmax\": 100, \n",
        "    \"initial_amount\": 1000000, \n",
        "    \"buy_cost_pct\": 0.001,\n",
        "    \"sell_cost_pct\": 0.001,\n",
        "    \"state_space\": state_space, \n",
        "    \"stock_dim\": stock_dimension, \n",
        "    \"tech_indicator_list\": ratio_list, \n",
        "    \"action_space\": stock_dimension, \n",
        "    \"reward_scaling\": 1e-4\n",
        "    \n",
        "}\n",
        "\n",
        "#Establish the training environment using StockTradingEnv() class\n",
        "e_train_gym = StockTradingEnv(df = train, **env_kwargs)"
      ],
      "execution_count": 32,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "64EoqOrQjiVf"
      },
      "source": [
        "## Environment for Training\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "xwSvvPjutpqS",
        "outputId": "1a9bc409-158a-4e25-afc4-0c0a10145670"
      },
      "source": [
        "env_train, _ = e_train_gym.get_sb_env()\n",
        "print(type(env_train))"
      ],
      "execution_count": 33,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "<class 'stable_baselines3.common.vec_env.dummy_vec_env.DummyVecEnv'>\n"
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HMNR5nHjh1iz"
      },
      "source": [
        "<a id='5'></a>\n",
        "# Part 6: Implement DRL Algorithms\n",
        "* The implementation of the DRL algorithms are based on **OpenAI Baselines** and **Stable Baselines**. Stable Baselines is a fork of OpenAI Baselines, with a major structural refactoring, and code cleanups.\n",
        "* FinRL library includes fine-tuned standard DRL algorithms, such as DQN, DDPG,\n",
        "Multi-Agent DDPG, PPO, SAC, A2C and TD3. We also allow users to\n",
        "design their own DRL algorithms by adapting these DRL algorithms."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "364PsqckttcQ"
      },
      "source": [
        "# Set up the agent using DRLAgent() class using the environment created in the previous part\n",
        "agent = DRLAgent(env = env_train)"
      ],
      "execution_count": 34,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YDmqOyF9h1iz"
      },
      "source": [
        "### Model Training: 5 models, A2C DDPG, PPO, TD3, SAC\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uijiWgkuh1jB"
      },
      "source": [
        "### Model 1: A2C\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "GUCnkn-HIbmj",
        "outputId": "255f52b4-15a6-47b7-9c7e-2913f497e156"
      },
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "model_a2c = agent.get_model(\"a2c\")"
      ],
      "execution_count": 35,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'n_steps': 5, 'ent_coef': 0.01, 'learning_rate': 0.0007}\n",
            "Using cuda device\n"
          ]
        }
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/",
          "height": 1000
        },
        "id": "0GVpkWGqH4-D",
        "outputId": "2dfdec32-47c2-420b-922f-4c4fd3afea84"
      },
      "source": [
        "trained_a2c = agent.train_model(model=model_a2c, \n",
        "                             tb_log_name='a2c',\n",
        "                             total_timesteps=100000)"
      ],
      "execution_count": 36,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "-----------------------------------------\n",
            "| time/                 |               |\n",
            "|    fps                | 85            |\n",
            "|    iterations         | 100           |\n",
            "|    time_elapsed       | 5             |\n",
            "|    total_timesteps    | 500           |\n",
            "| train/                |               |\n",
            "|    entropy_loss       | -42.7         |\n",
            "|    explained_variance | 0.00025       |\n",
            "|    learning_rate      | 0.0007        |\n",
            "|    n_updates          | 99            |\n",
            "|    policy_loss        | 72.9          |\n",
            "|    reward             | -0.0017323004 |\n",
            "|    std                | 1             |\n",
            "|    value_loss         | 5             |\n",
            "-----------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 86        |\n",
            "|    iterations         | 200       |\n",
            "|    time_elapsed       | 11        |\n",
            "|    total_timesteps    | 1000      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -42.7     |\n",
            "|    explained_variance | -1.19e-07 |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 199       |\n",
            "|    policy_loss        | 33.4      |\n",
            "|    reward             | 1.0503633 |\n",
            "|    std                | 1         |\n",
            "|    value_loss         | 4.55      |\n",
            "-------------------------------------\n",
            "-----------------------------------------\n",
            "| time/                 |               |\n",
            "|    fps                | 87            |\n",
            "|    iterations         | 300           |\n",
            "|    time_elapsed       | 17            |\n",
            "|    total_timesteps    | 1500          |\n",
            "| train/                |               |\n",
            "|    entropy_loss       | -42.7         |\n",
            "|    explained_variance | 0             |\n",
            "|    learning_rate      | 0.0007        |\n",
            "|    n_updates          | 299           |\n",
            "|    policy_loss        | 19.1          |\n",
            "|    reward             | -0.0030366322 |\n",
            "|    std                | 1.01          |\n",
            "|    value_loss         | 0.988         |\n",
            "-----------------------------------------\n",
            "-------------------------------------\n",
            "| time/                 |           |\n",
            "|    fps                | 87        |\n",
            "|    iterations         | 400       |\n",
            "|    time_elapsed       | 22        |\n",
            "|    total_timesteps    | 2000      |\n",
            "| train/                |           |\n",
            "|    entropy_loss       | -42.8     |\n",
            "|    explained_variance | 0         |\n",
            "|    learning_rate      | 0.0007    |\n",
            "|    n_updates          | 399       |\n",
            "|    policy_loss        | 29.4      |\n",
            "|    reward             | 1.5995015 |\n",
            "|    std                | 1.01      |\n",
            "|    value_loss         | 1.41      |\n",
            "-------------------------------------\n"
          ]
        },
        {
          "output_type": "error",
          "ename": "KeyboardInterrupt",
          "evalue": "ignored",
          "traceback": [
            "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m                         Traceback (most recent call last)",
            "\u001b[0;32m<ipython-input-36-e000b3012843>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      1\u001b[0m trained_a2c = agent.train_model(model=model_a2c, \n\u001b[1;32m      2\u001b[0m                              \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'a2c'\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m                              total_timesteps=100000)\n\u001b[0m",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/finrl/drl_agents/stablebaselines3/models.py\u001b[0m in \u001b[0;36mtrain_model\u001b[0;34m(self, model, tb_log_name, total_timesteps)\u001b[0m\n\u001b[1;32m    103\u001b[0m             \u001b[0mtotal_timesteps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtotal_timesteps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    104\u001b[0m             \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtb_log_name\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 105\u001b[0;31m             \u001b[0mcallback\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mTensorboardCallback\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    106\u001b[0m         )\n\u001b[1;32m    107\u001b[0m         \u001b[0;32mreturn\u001b[0m \u001b[0mmodel\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/a2c/a2c.py\u001b[0m in \u001b[0;36mlearn\u001b[0;34m(self, total_timesteps, callback, log_interval, eval_env, eval_freq, n_eval_episodes, tb_log_name, eval_log_path, reset_num_timesteps)\u001b[0m\n\u001b[1;32m    199\u001b[0m             \u001b[0mtb_log_name\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mtb_log_name\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    200\u001b[0m             \u001b[0meval_log_path\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0meval_log_path\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 201\u001b[0;31m             \u001b[0mreset_num_timesteps\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreset_num_timesteps\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    202\u001b[0m         )\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/common/on_policy_algorithm.py\u001b[0m in \u001b[0;36mlearn\u001b[0;34m(self, total_timesteps, callback, log_interval, eval_env, eval_freq, n_eval_episodes, tb_log_name, eval_log_path, reset_num_timesteps)\u001b[0m\n\u001b[1;32m    255\u001b[0m                 \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlogger\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdump\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mstep\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mnum_timesteps\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    256\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 257\u001b[0;31m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtrain\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    258\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    259\u001b[0m         \u001b[0mcallback\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mon_training_end\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/stable_baselines3/a2c/a2c.py\u001b[0m in \u001b[0;36mtrain\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m    160\u001b[0m             \u001b[0;31m# Optimization step\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    161\u001b[0m             \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpolicy\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moptimizer\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mzero_grad\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 162\u001b[0;31m             \u001b[0mloss\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    163\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    164\u001b[0m             \u001b[0;31m# Clip grad norm\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/_tensor.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(self, gradient, retain_graph, create_graph, inputs)\u001b[0m\n\u001b[1;32m    305\u001b[0m                 \u001b[0mcreate_graph\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcreate_graph\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    306\u001b[0m                 inputs=inputs)\n\u001b[0;32m--> 307\u001b[0;31m         \u001b[0mtorch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mautograd\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbackward\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgradient\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0minputs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m    308\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    309\u001b[0m     \u001b[0;32mdef\u001b[0m \u001b[0mregister_hook\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mhook\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;32m/usr/local/lib/python3.7/dist-packages/torch/autograd/__init__.py\u001b[0m in \u001b[0;36mbackward\u001b[0;34m(tensors, grad_tensors, retain_graph, create_graph, grad_variables, inputs)\u001b[0m\n\u001b[1;32m    154\u001b[0m     Variable._execution_engine.run_backward(\n\u001b[1;32m    155\u001b[0m         \u001b[0mtensors\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mgrad_tensors_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mretain_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcreate_graph\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minputs\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 156\u001b[0;31m         allow_unreachable=True, accumulate_grad=True)  # allow_unreachable flag\n\u001b[0m\u001b[1;32m    157\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m    158\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
            "\u001b[0;31mKeyboardInterrupt\u001b[0m: "
          ]
        }
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MRiOtrywfAo1"
      },
      "source": [
        "### Model 2: DDPG"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "M2YadjfnLwgt"
      },
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "model_ddpg = agent.get_model(\"ddpg\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "collapsed": true,
        "id": "tCDa78rqfO_a"
      },
      "source": [
        "trained_ddpg = agent.train_model(model=model_ddpg, \n",
        "                             tb_log_name='ddpg',\n",
        "                             total_timesteps=50000)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_gDkU-j-fCmZ"
      },
      "source": [
        "### Model 3: PPO"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "y5D5PFUhMzSV"
      },
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "PPO_PARAMS = {\n",
        "    \"n_steps\": 2048,\n",
        "    \"ent_coef\": 0.01,\n",
        "    \"learning_rate\": 0.00025,\n",
        "    \"batch_size\": 128,\n",
        "}\n",
        "model_ppo = agent.get_model(\"ppo\",model_kwargs = PPO_PARAMS)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "collapsed": true,
        "id": "Gt8eIQKYM4G3"
      },
      "source": [
        "trained_ppo = agent.train_model(model=model_ppo, \n",
        "                             tb_log_name='ppo',\n",
        "                             total_timesteps=50000)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "3Zpv4S0-fDBv"
      },
      "source": [
        "### Model 4: TD3"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "JSAHhV4Xc-bh"
      },
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "TD3_PARAMS = {\"batch_size\": 100, \n",
        "              \"buffer_size\": 1000000, \n",
        "              \"learning_rate\": 0.001}\n",
        "\n",
        "model_td3 = agent.get_model(\"td3\",model_kwargs = TD3_PARAMS)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "OSRxNYAxdKpU"
      },
      "source": [
        "trained_td3 = agent.train_model(model=model_td3, \n",
        "                             tb_log_name='td3',\n",
        "                             total_timesteps=30000)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Dr49PotrfG01"
      },
      "source": [
        "### Model 5: SAC"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "xwOhVjqRkCdM"
      },
      "source": [
        "agent = DRLAgent(env = env_train)\n",
        "SAC_PARAMS = {\n",
        "    \"batch_size\": 128,\n",
        "    \"buffer_size\": 1000000,\n",
        "    \"learning_rate\": 0.0001,\n",
        "    \"learning_starts\": 100,\n",
        "    \"ent_coef\": \"auto_0.1\",\n",
        "}\n",
        "\n",
        "model_sac = agent.get_model(\"sac\",model_kwargs = SAC_PARAMS)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "K8RSdKCckJyH"
      },
      "source": [
        "trained_sac = agent.train_model(model=model_sac, \n",
        "                             tb_log_name='sac',\n",
        "                             total_timesteps=80000)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "f2wZgkQXh1jE"
      },
      "source": [
        "## Trading\n",
        "Assume that we have $1,000,000 initial capital at 2019-01-01. We use the DDPG model to trade Dow jones 30 stocks."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "U5mmgQF_h1jQ"
      },
      "source": [
        "### Trade\n",
        "\n",
        "DRL model needs to update periodically in order to take full advantage of the data, ideally we need to retrain our model yearly, quarterly, or monthly. We also need to tune the parameters along the way, in this notebook I only use the in-sample data from 2009-01 to 2018-12 to tune the parameters once, so there is some alpha decay here as the length of trade date extends. \n",
        "\n",
        "Numerous hyperparameters – e.g. the learning rate, the total number of samples to train on – influence the learning process and are usually determined by testing some variations."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "cIqoV0GSI52v"
      },
      "source": [
        "trade = data_split(processed_full, '2019-01-01','2021-01-01')\n",
        "e_trade_gym = StockTradingEnv(df = trade, **env_kwargs)\n",
        "# env_trade, obs_trade = e_trade_gym.get_sb_env()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "W_XNgGsBMeVw"
      },
      "source": [
        "trade.head()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "eLOnL5eYh1jR"
      },
      "source": [
        "df_account_value, df_actions = DRLAgent.DRL_prediction(\n",
        "    model=trained_ddpg, \n",
        "    environment = e_trade_gym)"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "ERxw3KqLkcP4"
      },
      "source": [
        "df_account_value.shape"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "2yRkNguY5yvp"
      },
      "source": [
        "df_account_value.tail()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "nFlK5hNbWVFk"
      },
      "source": [
        "df_actions.head()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "W6vvNSC6h1jZ"
      },
      "source": [
        "<a id='6'></a>\n",
        "# Part 7: Backtest Our Strategy\n",
        "Backtesting plays a key role in evaluating the performance of a trading strategy. Automated backtesting tool is preferred because it reduces the human error. We usually use the Quantopian pyfolio package to backtest our trading strategies. It is easy to use and consists of various individual plots that provide a comprehensive image of the performance of a trading strategy."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Lr2zX7ZxNyFQ"
      },
      "source": [
        "<a id='6.1'></a>\n",
        "## 7.1 BackTestStats\n",
        "pass in df_account_value, this information is stored in env class\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "Nzkr9yv-AdV_"
      },
      "source": [
        "print(\"==============Get Backtest Results===========\")\n",
        "now = datetime.datetime.now().strftime('%Y%m%d-%Hh%M')\n",
        "\n",
        "perf_stats_all = backtest_stats(account_value=df_account_value)\n",
        "perf_stats_all = pd.DataFrame(perf_stats_all)\n",
        "perf_stats_all.to_csv(\"./\"+config.RESULTS_DIR+\"/perf_stats_all_\"+now+'.csv')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "QkV-LB66iwhD"
      },
      "source": [
        "#baseline stats\n",
        "print(\"==============Get Baseline Stats===========\")\n",
        "baseline_df = get_baseline(\n",
        "        ticker=\"^DJI\", \n",
        "        start = '2019-01-01',\n",
        "        end = '2021-01-01')\n",
        "\n",
        "stats = backtest_stats(baseline_df, value_col_name = 'close')\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "9U6Suru3h1jc"
      },
      "source": [
        "<a id='6.2'></a>\n",
        "## 7.2 BackTestPlot"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "lKRGftSS7pNM"
      },
      "source": [
        "print(\"==============Compare to DJIA===========\")\n",
        "%matplotlib inline\n",
        "# S&P 500: ^GSPC\n",
        "# Dow Jones Index: ^DJI\n",
        "# NASDAQ 100: ^NDX\n",
        "backtest_plot(df_account_value, \n",
        "             baseline_ticker = '^DJI', \n",
        "             baseline_start = '2019-01-01',\n",
        "             baseline_end = '2021-01-01')"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "BzBaE63H3RLc"
      },
      "source": [
        ""
      ],
      "execution_count": null,
      "outputs": []
    }
  ]
}